@levo-so/blocks 0.1.60 → 0.1.62
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 +13 -14
- package/src/blocks/about-us/about-us-1.schema.ts +15 -30
- package/src/blocks/about-us/about-us-1.tsx +2 -4
- package/src/blocks/about-us/about-us-2.schema.ts +24 -48
- package/src/blocks/about-us/about-us-2.tsx +7 -13
- package/src/blocks/blogs/blog-listing-1.schema.ts +7 -14
- package/src/blocks/blogs/blog-listing-1.tsx +10 -21
- package/src/blocks/blogs/blog-listing-2.schema.ts +17 -34
- package/src/blocks/blogs/blog-listing-2.tsx +4 -12
- package/src/blocks/blogs/blog-listing-3.schema.ts +32 -64
- package/src/blocks/blogs/blog-listing-3.tsx +4 -12
- package/src/blocks/blogs/blog-post-1.schema.ts +9 -18
- package/src/blocks/blogs/blog-post-1.tsx +3 -14
- package/src/blocks/calendar/calendar-1.schema.ts +95 -6
- package/src/blocks/calendar/calendar-1.tsx +33 -29
- package/src/blocks/cards/cards-10.schema.ts +62 -124
- package/src/blocks/cards/cards-10.tsx +9 -14
- package/src/blocks/cards/cards-11.schema.ts +69 -138
- package/src/blocks/cards/cards-11.tsx +5 -11
- package/src/blocks/cards/cards-12.schema.ts +7 -14
- package/src/blocks/cards/cards-12.tsx +4 -10
- package/src/blocks/cards/cards-13.schema.ts +40 -80
- package/src/blocks/cards/cards-13.tsx +4 -6
- package/src/blocks/cards/cards-14.schema.ts +7 -14
- package/src/blocks/cards/cards-14.tsx +5 -11
- package/src/blocks/cards/cards-15.schema.ts +7 -14
- package/src/blocks/cards/cards-15.tsx +2 -4
- package/src/blocks/cards/cards-2.schema.ts +7 -14
- package/src/blocks/cards/cards-2.tsx +2 -15
- package/src/blocks/cards/cards-3.schema.ts +7 -14
- package/src/blocks/cards/cards-3.tsx +7 -13
- package/src/blocks/cards/cards-4.schema.ts +13 -26
- package/src/blocks/cards/cards-4.tsx +9 -15
- package/src/blocks/cards/cards-5.schema.ts +17 -34
- package/src/blocks/cards/cards-5.tsx +1 -9
- package/src/blocks/cards/cards-6.schema.ts +52 -104
- package/src/blocks/cards/cards-6.tsx +12 -20
- package/src/blocks/cards/cards-7.schema.ts +48 -96
- package/src/blocks/cards/cards-7.tsx +8 -27
- package/src/blocks/cards/cards-8.schema.ts +9 -20
- package/src/blocks/cards/cards-8.tsx +5 -11
- package/src/blocks/cards/cards-9.schema.ts +41 -82
- package/src/blocks/cards/cards-9.tsx +14 -22
- package/src/blocks/carousel/carousel-1.schema.ts +64 -128
- package/src/blocks/carousel/carousel-1.tsx +6 -8
- package/src/blocks/carousel/carousel-2.schema.ts +26 -52
- package/src/blocks/carousel/carousel-2.tsx +11 -23
- package/src/blocks/community/community-1.schema.ts +78 -32
- package/src/blocks/community/community-1.tsx +417 -550
- package/src/blocks/community/community-post-1.schema.ts +21 -30
- package/src/blocks/community/community-post-1.tsx +334 -84
- package/src/blocks/contact-us/contact-us-1.schema.ts +8 -16
- package/src/blocks/contact-us/contact-us-1.tsx +2 -12
- package/src/blocks/contact-us/contact-us-2.tsx +20 -31
- package/src/blocks/content/content-1.schema.ts +21 -42
- package/src/blocks/content/content-1.tsx +10 -17
- package/src/blocks/content/content-2.schema.ts +29 -58
- package/src/blocks/content/content-2.tsx +4 -4
- package/src/blocks/content/content-3.tsx +13 -29
- package/src/blocks/content/content-4.schema.ts +23 -46
- package/src/blocks/content/content-4.tsx +8 -17
- package/src/blocks/content/content-5.schema.ts +29 -24
- package/src/blocks/content/content-5.tsx +13 -27
- package/src/blocks/content/content-6.schema.ts +46 -94
- package/src/blocks/content/content-6.tsx +14 -31
- package/src/blocks/content/content-7.schema.ts +35 -72
- package/src/blocks/content/content-7.tsx +15 -31
- package/src/blocks/content/content-8.schema.ts +1 -6
- package/src/blocks/content/content-8.tsx +3 -3
- package/src/blocks/content/content-9.tsx +26 -41
- package/src/blocks/cta/cta-1.schema.ts +10 -20
- package/src/blocks/cta/cta-2.schema.ts +14 -28
- package/src/blocks/cta/cta-2.tsx +2 -6
- package/src/blocks/cta/cta-3.schema.ts +24 -50
- package/src/blocks/cta/cta-3.tsx +2 -6
- package/src/blocks/embed/embed-1.tsx +1 -9
- package/src/blocks/event/ClientOnly.tsx +1 -4
- package/src/blocks/event/event-details.schema.ts +16 -32
- package/src/blocks/event/event-details.tsx +8 -23
- package/src/blocks/event/event-listing-2.schema.ts +19 -38
- package/src/blocks/event/event-listing-2.tsx +12 -23
- package/src/blocks/event/event-listing-3.schema.ts +10 -20
- package/src/blocks/event/event-listing-3.tsx +9 -15
- package/src/blocks/event/event-listing-4.schema.ts +40 -80
- package/src/blocks/event/event-listing-4.tsx +5 -13
- package/src/blocks/event/event-listing.schema.ts +12 -24
- package/src/blocks/event/event-listing.tsx +9 -15
- package/src/blocks/faq/faq-1.schema.ts +8 -16
- package/src/blocks/faq/faq-1.tsx +19 -30
- package/src/blocks/faq/faq-2.schema.ts +8 -16
- package/src/blocks/faq/faq-2.tsx +11 -10
- package/src/blocks/faq/faq-3.schema.ts +9 -18
- package/src/blocks/faq/faq-3.tsx +11 -19
- package/src/blocks/features/features-1/features-1.tsx +2 -4
- package/src/blocks/features/features-1/variants/default.ts +4 -8
- package/src/blocks/features/features-1/variants/index.ts +1 -1
- package/src/blocks/features/features-2.schema.ts +32 -64
- package/src/blocks/features/features-2.tsx +8 -10
- package/src/blocks/features/features-3.schema.ts +32 -64
- package/src/blocks/features/features-3.tsx +7 -16
- package/src/blocks/features/features-4.schema.ts +16 -32
- package/src/blocks/features/features-4.tsx +3 -7
- package/src/blocks/features/features-5.schema.ts +1 -2
- package/src/blocks/features/features-5.tsx +6 -17
- package/src/blocks/features/features-6.schema.ts +32 -64
- package/src/blocks/features/features-6.tsx +16 -36
- package/src/blocks/filter-listing/filter-listing-1.tsx +12 -36
- package/src/blocks/floating-buttons/floating-button-1.schema.ts +5 -10
- package/src/blocks/floating-buttons/floating-button-1.tsx +3 -9
- package/src/blocks/footer/footer-1.schema.ts +8 -16
- package/src/blocks/footer/footer-1.tsx +15 -30
- package/src/blocks/footer/footer-2.schema.ts +8 -16
- package/src/blocks/footer/footer-2.tsx +17 -28
- package/src/blocks/footer/footer-3.schema.ts +1 -2
- package/src/blocks/footer/footer-3.tsx +9 -25
- package/src/blocks/footer/footer-4.schema.ts +8 -16
- package/src/blocks/footer/footer-4.tsx +35 -54
- package/src/blocks/footer/footer-5.schema.ts +10 -24
- package/src/blocks/footer/footer-5.tsx +14 -29
- package/src/blocks/footer/footer-6.schema.ts +10 -25
- package/src/blocks/footer/footer-6.tsx +29 -44
- package/src/blocks/form/form-1.schema.ts +144 -0
- package/src/blocks/form/form-1.tsx +33 -0
- package/src/blocks/hero/hero-1.schema.ts +45 -90
- package/src/blocks/hero/hero-1.tsx +4 -4
- package/src/blocks/hero/hero-10.schema.ts +1 -2
- package/src/blocks/hero/hero-10.tsx +4 -4
- package/src/blocks/hero/hero-11.schema.ts +18 -14
- package/src/blocks/hero/hero-11.tsx +4 -9
- package/src/blocks/hero/hero-12.schema.ts +18 -36
- package/src/blocks/hero/hero-12.tsx +3 -6
- package/src/blocks/hero/hero-13.schema.ts +8 -16
- package/src/blocks/hero/hero-13.tsx +1 -1
- package/src/blocks/hero/hero-2.schema.ts +3 -6
- package/src/blocks/hero/hero-2.tsx +3 -21
- package/src/blocks/hero/hero-3.schema.ts +28 -56
- package/src/blocks/hero/hero-3.tsx +6 -15
- package/src/blocks/hero/hero-4.schema.ts +22 -44
- package/src/blocks/hero/hero-4.tsx +16 -27
- package/src/blocks/hero/hero-5.schema.ts +21 -42
- package/src/blocks/hero/hero-5.tsx +15 -18
- package/src/blocks/hero/hero-6.schema.ts +35 -70
- package/src/blocks/hero/hero-6.tsx +6 -6
- package/src/blocks/hero/hero-7.schema.ts +24 -48
- package/src/blocks/hero/hero-7.tsx +2 -3
- package/src/blocks/hero/hero-8.schema.ts +24 -50
- package/src/blocks/hero/hero-8.tsx +5 -19
- package/src/blocks/hero/hero-9.schema.ts +8 -16
- package/src/blocks/hero/hero-9.tsx +3 -3
- package/src/blocks/index.ts +8 -11
- package/src/blocks/jobs/jobs-1.schema.ts +990 -0
- package/src/blocks/jobs/jobs-1.tsx +145 -0
- package/src/blocks/logos/logos-1.schema.ts +53 -113
- package/src/blocks/logos/logos-1.tsx +7 -7
- package/src/blocks/navbar/navbar-1.schema.ts +15 -28
- package/src/blocks/navbar/navbar-1.tsx +24 -60
- package/src/blocks/navbar/navbar-2.schema.ts +14 -28
- package/src/blocks/navbar/navbar-2.tsx +26 -56
- package/src/blocks/navbar/navbar-3.schema.ts +11 -22
- package/src/blocks/navbar/navbar-3.tsx +33 -82
- package/src/blocks/navbar/navbar-4.schema.ts +14343 -0
- package/src/blocks/navbar/navbar-4.tsx +546 -0
- package/src/blocks/polling/polling-1.schema.ts +1 -2
- package/src/blocks/polling/polling-1.tsx +24 -39
- package/src/blocks/pricing/pricing-1.schema.ts +13 -26
- package/src/blocks/pricing/pricing-1.tsx +20 -44
- package/src/blocks/products/products-listing-1.schema.ts +32 -64
- package/src/blocks/products/products-listing-1.tsx +6 -12
- package/src/blocks/products/products-listing-2.schema.ts +26 -54
- package/src/blocks/products/products-listing-2.tsx +8 -17
- package/src/blocks/products/products-listing-3.schema.ts +25 -52
- package/src/blocks/products/products-listing-3.tsx +87 -93
- package/src/blocks/profile/profile-1.schema.ts +7 -14
- package/src/blocks/profile/profile-1.tsx +2 -8
- package/src/blocks/profile/profile-2.schema.ts +9 -18
- package/src/blocks/profile/profile-2.tsx +4 -6
- package/src/blocks/profile/profile-3.schema.ts +21 -42
- package/src/blocks/profile/profile-3.tsx +18 -40
- package/src/blocks/{blogs/blog-post-2.schema.ts → profile/profile-4.schema.ts} +75 -97
- package/src/blocks/{blogs/blog-post-2.tsx → profile/profile-4.tsx} +32 -61
- package/src/blocks/{blogs/blog-post-3.schema.ts → profile/profile-5.schema.ts} +6 -6
- package/src/blocks/{blogs/blog-post-3.tsx → profile/profile-5.tsx} +6 -11
- package/src/blocks/services/service-1.schema.ts +20 -40
- package/src/blocks/services/service-1.tsx +45 -71
- package/src/blocks/services/service-2.schema.ts +8 -16
- package/src/blocks/services/service-2.tsx +4 -6
- package/src/blocks/services/service-3.schema.ts +12 -24
- package/src/blocks/services/service-3.tsx +4 -6
- package/src/blocks/stats/stats-1.tsx +3 -14
- package/src/blocks/stats/stats-2.tsx +3 -14
- package/src/blocks/stats/variants/index.ts +1 -1
- package/src/blocks/tabs/tab-1.schema.ts +4 -8
- package/src/blocks/tabs/tab-1.tsx +47 -64
- package/src/blocks/tabs/tab-2.schema.ts +13 -26
- package/src/blocks/tabs/tab-2.tsx +14 -15
- package/src/blocks/team/team-1.schema.ts +28 -56
- package/src/blocks/team/team-1.tsx +7 -21
- package/src/blocks/team/team-2.schema.ts +104 -208
- package/src/blocks/team/team-2.tsx +15 -33
- package/src/blocks/team/team-3.schema.ts +24 -48
- package/src/blocks/team/team-3.tsx +8 -14
- package/src/blocks/team/team-4.schema.ts +25 -50
- package/src/blocks/team/team-4.tsx +15 -24
- package/src/blocks/team/team-5.schema.ts +14 -28
- package/src/blocks/team/team-5.tsx +1 -1
- package/src/blocks/termsAndPrivacy/terms-and-conditions-1.tsx +3 -5
- package/src/blocks/testimonial/testimonial-1.schema.ts +1 -2
- package/src/blocks/testimonial/testimonial-1.tsx +10 -19
- package/src/blocks/testimonial/testimonial-2.schema.ts +16 -32
- package/src/blocks/testimonial/testimonial-2.tsx +17 -36
- package/src/blocks/testimonial/testimonial-3.schema.ts +8 -16
- package/src/blocks/testimonial/testimonial-3.tsx +13 -26
- package/src/blocks/testimonial/testimonial-4.schema.ts +94 -188
- package/src/blocks/testimonial/testimonial-4.tsx +12 -33
- package/src/blocks/testimonial/testimonial-5/variants/default.ts +24 -48
- package/src/blocks/testimonial/testimonial-5/variants/index.ts +1 -1
- package/src/blocks/testimonial/testimonial-5/variants/testimonialWithLogo.ts +4 -8
- package/src/blocks/testimonial/testimonial-5/variants/testimonialWithRatings.ts +24 -48
- package/src/blocks/testimonial/testimonial-5.schema.ts +2 -6
- package/src/blocks/testimonial/testimonial-5.tsx +15 -25
- package/src/blocks/testimonial/testimonial-6.schema.ts +26 -52
- package/src/blocks/testimonial/testimonial-6.tsx +9 -25
- package/src/blocks/testimonial/testimonial-7.tsx +15 -26
- package/src/blocks/timeline/timeline-1.schema.ts +34 -68
- package/src/blocks/timeline/timeline-1.tsx +2 -6
- package/src/blocks/users/edit-profile.tsx +10 -22
- package/src/constants/index.ts +3 -6
- package/src/index.ts +1 -1
- package/src/schemas/blocks.ts +14 -8
- package/src/schemas/categories.ts +14 -2
|
@@ -4,6 +4,7 @@ const DEFAULT_CONTENT = {
|
|
|
4
4
|
layout: null,
|
|
5
5
|
container: null,
|
|
6
6
|
post: "{context.forum}",
|
|
7
|
+
forum_key: "forum",
|
|
7
8
|
sidebar_links_levoGroup: null,
|
|
8
9
|
sidebar_links: [
|
|
9
10
|
{
|
|
@@ -43,43 +44,28 @@ const DEFAULT_CONTENT = {
|
|
|
43
44
|
kind: "image",
|
|
44
45
|
location: "https://static.levostg.online/WZZKMUBH/banner-HXVr5tikleqvq.png",
|
|
45
46
|
srcset: {
|
|
46
|
-
"1080w":
|
|
47
|
-
|
|
48
|
-
"
|
|
49
|
-
|
|
50
|
-
"
|
|
51
|
-
|
|
52
|
-
"
|
|
53
|
-
"https://static.levostg.online/WZZKMUBH/banner-HXVr5tikleqvq-320w.webp",
|
|
54
|
-
"640w":
|
|
55
|
-
"https://static.levostg.online/WZZKMUBH/banner-HXVr5tikleqvq-640w.webp",
|
|
56
|
-
"750w":
|
|
57
|
-
"https://static.levostg.online/WZZKMUBH/banner-HXVr5tikleqvq-750w.webp",
|
|
58
|
-
"828w":
|
|
59
|
-
"https://static.levostg.online/WZZKMUBH/banner-HXVr5tikleqvq-828w.webp",
|
|
47
|
+
"1080w": "https://static.levostg.online/WZZKMUBH/banner-HXVr5tikleqvq-1080w.webp",
|
|
48
|
+
"1200w": "https://static.levostg.online/WZZKMUBH/banner-HXVr5tikleqvq-1200w.webp",
|
|
49
|
+
"1920w": "https://static.levostg.online/WZZKMUBH/banner-HXVr5tikleqvq-1920w.webp",
|
|
50
|
+
"320w": "https://static.levostg.online/WZZKMUBH/banner-HXVr5tikleqvq-320w.webp",
|
|
51
|
+
"640w": "https://static.levostg.online/WZZKMUBH/banner-HXVr5tikleqvq-640w.webp",
|
|
52
|
+
"750w": "https://static.levostg.online/WZZKMUBH/banner-HXVr5tikleqvq-750w.webp",
|
|
53
|
+
"828w": "https://static.levostg.online/WZZKMUBH/banner-HXVr5tikleqvq-828w.webp",
|
|
60
54
|
path: "https://static.levostg.online/WZZKMUBH/banner-HXVr5tikleqvq-320w.webp 320w, https://static.levostg.online/WZZKMUBH/banner-HXVr5tikleqvq-640w.webp 640w, https://static.levostg.online/WZZKMUBH/banner-HXVr5tikleqvq-750w.webp 750w, https://static.levostg.online/WZZKMUBH/banner-HXVr5tikleqvq-828w.webp 828w, https://static.levostg.online/WZZKMUBH/banner-HXVr5tikleqvq-1080w.webp 1080w, https://static.levostg.online/WZZKMUBH/banner-HXVr5tikleqvq-1200w.webp 1200w, https://static.levostg.online/WZZKMUBH/banner-HXVr5tikleqvq-1920w.webp 1920w",
|
|
61
55
|
},
|
|
62
56
|
},
|
|
63
57
|
edit_profile_block_logo: {
|
|
64
58
|
id: "zucZ9wWTU6qEL",
|
|
65
59
|
kind: "image",
|
|
66
|
-
location:
|
|
67
|
-
"https://static.levostg.online/WZZKMUBH/netflix-FUGaJXflpOINw.jpeg",
|
|
60
|
+
location: "https://static.levostg.online/WZZKMUBH/netflix-FUGaJXflpOINw.jpeg",
|
|
68
61
|
srcset: {
|
|
69
|
-
"1080w":
|
|
70
|
-
|
|
71
|
-
"
|
|
72
|
-
|
|
73
|
-
"
|
|
74
|
-
|
|
75
|
-
"
|
|
76
|
-
"https://static.levostg.online/WZZKMUBH/netflix-FUGaJXflpOINw-320w.webp",
|
|
77
|
-
"640w":
|
|
78
|
-
"https://static.levostg.online/WZZKMUBH/netflix-FUGaJXflpOINw-640w.webp",
|
|
79
|
-
"750w":
|
|
80
|
-
"https://static.levostg.online/WZZKMUBH/netflix-FUGaJXflpOINw-750w.webp",
|
|
81
|
-
"828w":
|
|
82
|
-
"https://static.levostg.online/WZZKMUBH/netflix-FUGaJXflpOINw-828w.webp",
|
|
62
|
+
"1080w": "https://static.levostg.online/WZZKMUBH/netflix-FUGaJXflpOINw-1080w.webp",
|
|
63
|
+
"1200w": "https://static.levostg.online/WZZKMUBH/netflix-FUGaJXflpOINw-1200w.webp",
|
|
64
|
+
"1920w": "https://static.levostg.online/WZZKMUBH/netflix-FUGaJXflpOINw-1920w.webp",
|
|
65
|
+
"320w": "https://static.levostg.online/WZZKMUBH/netflix-FUGaJXflpOINw-320w.webp",
|
|
66
|
+
"640w": "https://static.levostg.online/WZZKMUBH/netflix-FUGaJXflpOINw-640w.webp",
|
|
67
|
+
"750w": "https://static.levostg.online/WZZKMUBH/netflix-FUGaJXflpOINw-750w.webp",
|
|
68
|
+
"828w": "https://static.levostg.online/WZZKMUBH/netflix-FUGaJXflpOINw-828w.webp",
|
|
83
69
|
path: "https://static.levostg.online/WZZKMUBH/netflix-FUGaJXflpOINw-1200w.webp 1200w, https://static.levostg.online/WZZKMUBH/netflix-FUGaJXflpOINw-1920w.webp 1920w, https://static.levostg.online/WZZKMUBH/netflix-FUGaJXflpOINw-320w.webp 320w, https://static.levostg.online/WZZKMUBH/netflix-FUGaJXflpOINw-640w.webp 640w, https://static.levostg.online/WZZKMUBH/netflix-FUGaJXflpOINw-750w.webp 750w, https://static.levostg.online/WZZKMUBH/netflix-FUGaJXflpOINw-828w.webp 828w, https://static.levostg.online/WZZKMUBH/netflix-FUGaJXflpOINw-1080w.webp 1080w",
|
|
84
70
|
},
|
|
85
71
|
},
|
|
@@ -105,6 +91,11 @@ export const CommunityPost1: IBlock = {
|
|
|
105
91
|
label: "Container",
|
|
106
92
|
field_interface: "LayoutWidget",
|
|
107
93
|
},
|
|
94
|
+
{
|
|
95
|
+
key: "forum_key",
|
|
96
|
+
label: "Forum Key",
|
|
97
|
+
field_interface: "HeadingWidget",
|
|
98
|
+
},
|
|
108
99
|
{
|
|
109
100
|
key: "left_container",
|
|
110
101
|
label: "Left Container",
|
|
@@ -1,47 +1,210 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
2
|
+
getLevoError,
|
|
3
|
+
type IForum,
|
|
4
|
+
type IForumJoinRequest,
|
|
5
|
+
type IForumMember,
|
|
6
|
+
type IForumMembershipStatus,
|
|
7
|
+
type IForumPost,
|
|
8
|
+
type IResponseSingle,
|
|
9
|
+
} from "@levo-so/core";
|
|
10
|
+
import { useLevo } from "@levo-so/react";
|
|
11
|
+
import {
|
|
5
12
|
Box,
|
|
6
|
-
ForumPost,
|
|
7
|
-
Comments,
|
|
8
13
|
Button,
|
|
9
|
-
|
|
14
|
+
Comments,
|
|
15
|
+
CommentsRestrictionOverlay,
|
|
16
|
+
Container,
|
|
17
|
+
ForumPost,
|
|
18
|
+
ForumProvider,
|
|
10
19
|
Heading,
|
|
20
|
+
type ILevoBlockBaseProps,
|
|
21
|
+
Media,
|
|
22
|
+
PostsRestrictionOverlay,
|
|
23
|
+
SamplePostSkeleton,
|
|
24
|
+
Section,
|
|
25
|
+
Skeleton,
|
|
11
26
|
Typography,
|
|
27
|
+
useAuth,
|
|
12
28
|
} from "@levo-so/studio";
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
15
|
-
type IForumPost,
|
|
16
|
-
type IResponseSingle,
|
|
17
|
-
getLevoError,
|
|
18
|
-
} from "@levo-so/core";
|
|
19
|
-
import { useEffect, useRef, useState } from "react";
|
|
29
|
+
import { useCallback, useEffect, useRef, useState } from "react";
|
|
20
30
|
|
|
21
31
|
import type { ICommunityPost1Content } from "./community-post-1.schema";
|
|
22
32
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
33
|
+
/** Map API error codes to user-friendly messages */
|
|
34
|
+
const JOIN_REQUEST_ERROR_MESSAGES: { [key: number]: string } = {
|
|
35
|
+
12111: "This forum doesn't require join requests.",
|
|
36
|
+
12112: "Join requests are not enabled for this forum.",
|
|
37
|
+
12113: "You are already a member of this forum.",
|
|
38
|
+
12114: "You have already submitted a join request.",
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
/** Skeleton for post detail page loading state */
|
|
42
|
+
const PostDetailSkeleton: React.FC = () => (
|
|
43
|
+
<div className="flex flex-col gap-4">
|
|
44
|
+
{/* Post skeleton */}
|
|
45
|
+
<div className="flex flex-col gap-3 rounded-lg border border-[#E5E5E5] bg-white p-4">
|
|
46
|
+
<div className="flex items-center gap-2">
|
|
47
|
+
<Skeleton className="h-10 w-10 rounded-full" />
|
|
48
|
+
<div className="flex flex-col gap-1">
|
|
49
|
+
<Skeleton className="h-4 w-28" />
|
|
50
|
+
<Skeleton className="h-3 w-20" />
|
|
51
|
+
</div>
|
|
52
|
+
</div>
|
|
53
|
+
<div className="space-y-2">
|
|
54
|
+
<Skeleton className="h-6 w-3/4" />
|
|
55
|
+
<Skeleton className="h-4 w-full" />
|
|
56
|
+
<Skeleton className="h-4 w-full" />
|
|
57
|
+
<Skeleton className="h-4 w-2/3" />
|
|
58
|
+
</div>
|
|
59
|
+
<div className="mt-2 flex items-center gap-4">
|
|
60
|
+
<Skeleton className="h-8 w-20 rounded-lg" />
|
|
61
|
+
<Skeleton className="h-8 w-16 rounded-lg" />
|
|
62
|
+
<Skeleton className="h-8 w-20 rounded-lg" />
|
|
63
|
+
</div>
|
|
64
|
+
</div>
|
|
65
|
+
{/* Comments skeleton */}
|
|
66
|
+
<div className="flex flex-col gap-4">
|
|
67
|
+
<Skeleton className="h-10 w-full rounded-lg" />
|
|
68
|
+
<div className="flex gap-3">
|
|
69
|
+
<Skeleton className="h-10 w-10 rounded-full" />
|
|
70
|
+
<div className="flex-1 space-y-2">
|
|
71
|
+
<Skeleton className="h-4 w-32" />
|
|
72
|
+
<Skeleton className="h-4 w-full" />
|
|
73
|
+
<Skeleton className="h-4 w-3/4" />
|
|
74
|
+
</div>
|
|
75
|
+
</div>
|
|
76
|
+
<div className="flex gap-3">
|
|
77
|
+
<Skeleton className="h-10 w-10 rounded-full" />
|
|
78
|
+
<div className="flex-1 space-y-2">
|
|
79
|
+
<Skeleton className="h-4 w-28" />
|
|
80
|
+
<Skeleton className="h-4 w-full" />
|
|
81
|
+
<Skeleton className="h-4 w-1/2" />
|
|
82
|
+
</div>
|
|
83
|
+
</div>
|
|
84
|
+
</div>
|
|
85
|
+
</div>
|
|
86
|
+
);
|
|
87
|
+
|
|
88
|
+
const CommunityPost1: React.FC<ILevoBlockBaseProps<ICommunityPost1Content>> = ({ content }) => {
|
|
26
89
|
const { fetch, logger } = useLevo();
|
|
27
|
-
const
|
|
28
|
-
|
|
90
|
+
const { isLoggedIn } = useAuth();
|
|
91
|
+
const [fetchedPostData, setFetchedPostData] = useState<Partial<IForumPost> | null>(null);
|
|
29
92
|
const [commentCount, setCommentCount] = useState(
|
|
30
93
|
(content?.post as unknown as IForumPost)?.comments_count ?? 0,
|
|
31
94
|
);
|
|
32
95
|
const hasFetchedRef = useRef(false);
|
|
33
96
|
const failedAttemptsRef = useRef(0);
|
|
97
|
+
const hasFetchedForumRef = useRef(false);
|
|
98
|
+
const failedForumAttemptsRef = useRef(0);
|
|
99
|
+
const hasFetchedMembershipRef = useRef(false);
|
|
100
|
+
const failedMembershipAttemptsRef = useRef(0);
|
|
101
|
+
const [forumData, setForumData] = useState<IForum | null>(null);
|
|
102
|
+
const [isMember, setIsMember] = useState<boolean>(false);
|
|
103
|
+
const [isLoadingMembership, setIsLoadingMembership] = useState(false);
|
|
104
|
+
const [joinRequest, setJoinRequest] = useState<IForumJoinRequest | null>(null);
|
|
34
105
|
|
|
35
106
|
const postSlug = (content?.post as unknown as IForumPost)?.slug;
|
|
107
|
+
const forumKey = content?.forum_key as unknown as string;
|
|
108
|
+
|
|
109
|
+
const fetchForumData = useCallback(async () => {
|
|
110
|
+
if (!forumKey || hasFetchedForumRef.current || failedForumAttemptsRef.current >= 3) return;
|
|
111
|
+
|
|
112
|
+
try {
|
|
113
|
+
const response = await fetch
|
|
114
|
+
.url(`/v1/community/${forumKey}/get-single`)
|
|
115
|
+
.get()
|
|
116
|
+
.json<IResponseSingle<IForum>>();
|
|
117
|
+
|
|
118
|
+
if (response?.content?.data) {
|
|
119
|
+
setForumData(response.content.data);
|
|
120
|
+
hasFetchedForumRef.current = true;
|
|
121
|
+
}
|
|
122
|
+
} catch (error) {
|
|
123
|
+
const levoError = getLevoError(error);
|
|
124
|
+
logger?.error("Failed to fetch forum data", levoError);
|
|
125
|
+
failedForumAttemptsRef.current += 1;
|
|
126
|
+
}
|
|
127
|
+
}, [forumKey, fetch, logger]);
|
|
128
|
+
|
|
129
|
+
const checkMembership = useCallback(async () => {
|
|
130
|
+
if (!forumData?.settings?.invite_only || !isLoggedIn) {
|
|
131
|
+
setIsMember(false);
|
|
132
|
+
setJoinRequest(null);
|
|
133
|
+
hasFetchedMembershipRef.current = true;
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
if (hasFetchedMembershipRef.current || failedMembershipAttemptsRef.current >= 3) {
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
setIsLoadingMembership(true);
|
|
142
|
+
|
|
143
|
+
try {
|
|
144
|
+
const response = await fetch
|
|
145
|
+
.url(`/v1/community/${forumKey}/member/get-me`)
|
|
146
|
+
.get()
|
|
147
|
+
.json<IResponseSingle<IForumMembershipStatus>>();
|
|
148
|
+
|
|
149
|
+
const data = response?.content?.data;
|
|
150
|
+
setIsMember(!!data?.member);
|
|
151
|
+
setJoinRequest(data?.join_request || null);
|
|
152
|
+
hasFetchedMembershipRef.current = true;
|
|
153
|
+
} catch (error) {
|
|
154
|
+
const levoError = getLevoError(error);
|
|
155
|
+
logger?.error("Failed to check membership", levoError);
|
|
156
|
+
setIsMember(false);
|
|
157
|
+
setJoinRequest(null);
|
|
158
|
+
failedMembershipAttemptsRef.current += 1;
|
|
159
|
+
} finally {
|
|
160
|
+
setIsLoadingMembership(false);
|
|
161
|
+
}
|
|
162
|
+
}, [forumKey, forumData?.settings?.invite_only, isLoggedIn, fetch, logger]);
|
|
163
|
+
|
|
164
|
+
/** Submit a join request for the current user */
|
|
165
|
+
const handleSubmitJoinRequest = useCallback(
|
|
166
|
+
async (message?: string): Promise<boolean> => {
|
|
167
|
+
try {
|
|
168
|
+
const response = await fetch
|
|
169
|
+
.url(`/v1/community/${forumKey}/join-request/submit`)
|
|
170
|
+
.post({ message })
|
|
171
|
+
.json<IResponseSingle<IForumJoinRequest>>();
|
|
172
|
+
|
|
173
|
+
if (response?.content?.data) {
|
|
174
|
+
setJoinRequest(response.content.data);
|
|
175
|
+
return true;
|
|
176
|
+
}
|
|
177
|
+
return false;
|
|
178
|
+
} catch (error) {
|
|
179
|
+
const levoError = getLevoError(error);
|
|
180
|
+
logger?.error("Failed to submit join request", levoError);
|
|
181
|
+
|
|
182
|
+
// Throw with user-friendly message
|
|
183
|
+
const errorMessage =
|
|
184
|
+
JOIN_REQUEST_ERROR_MESSAGES[levoError.code as any] || levoError.message;
|
|
185
|
+
throw new Error(errorMessage);
|
|
186
|
+
}
|
|
187
|
+
},
|
|
188
|
+
[forumKey, fetch, logger],
|
|
189
|
+
);
|
|
190
|
+
|
|
191
|
+
useEffect(() => {
|
|
192
|
+
fetchForumData();
|
|
193
|
+
}, [fetchForumData]);
|
|
194
|
+
|
|
195
|
+
useEffect(() => {
|
|
196
|
+
if (forumData) {
|
|
197
|
+
checkMembership();
|
|
198
|
+
}
|
|
199
|
+
}, [forumData, checkMembership]);
|
|
36
200
|
|
|
37
201
|
useEffect(() => {
|
|
38
202
|
const fetchPostVotes = async () => {
|
|
39
|
-
if (!postSlug || hasFetchedRef.current || failedAttemptsRef.current >= 3)
|
|
40
|
-
return;
|
|
203
|
+
if (!postSlug || hasFetchedRef.current || failedAttemptsRef.current >= 3) return;
|
|
41
204
|
|
|
42
205
|
try {
|
|
43
206
|
const response = await fetch
|
|
44
|
-
.url(`/v1/community/
|
|
207
|
+
.url(`/v1/community/${forumKey}/post/${postSlug}/get-single`)
|
|
45
208
|
.get()
|
|
46
209
|
.json<IResponseSingle<IForumPost>>();
|
|
47
210
|
|
|
@@ -78,77 +241,164 @@ const CommunityPost1: React.FC<ILevoBlockBaseProps<ICommunityPost1Content>> = ({
|
|
|
78
241
|
setCommentCount((prev) => prev + delta);
|
|
79
242
|
};
|
|
80
243
|
|
|
81
|
-
const isLoadingPostData =
|
|
82
|
-
|
|
244
|
+
const isLoadingPostData = !hasFetchedRef.current && failedAttemptsRef.current < 3;
|
|
245
|
+
|
|
246
|
+
/** Check if we're still loading forum data */
|
|
247
|
+
const isLoadingForumData = !hasFetchedForumRef.current && failedForumAttemptsRef.current < 3;
|
|
248
|
+
|
|
249
|
+
/** Check if we're still loading membership (only relevant for invite-only forums) */
|
|
250
|
+
const isCheckingMembership =
|
|
251
|
+
forumData?.settings?.invite_only &&
|
|
252
|
+
!hasFetchedMembershipRef.current &&
|
|
253
|
+
failedMembershipAttemptsRef.current < 3;
|
|
254
|
+
|
|
255
|
+
/**
|
|
256
|
+
* Show skeleton until all required data is fetched:
|
|
257
|
+
* - Forum data must be loaded
|
|
258
|
+
* - Membership check must be complete (for invite-only forums)
|
|
259
|
+
* - Post data should be available
|
|
260
|
+
*/
|
|
261
|
+
const isInitialLoading = isLoadingForumData || isCheckingMembership || isLoadingMembership;
|
|
262
|
+
|
|
263
|
+
const isInviteOnly = forumData?.settings?.invite_only ?? false;
|
|
264
|
+
const allowJoinRequests = forumData?.settings?.allow_join_requests ?? false;
|
|
265
|
+
|
|
266
|
+
/**
|
|
267
|
+
* Check if posts should be restricted (show overlay):
|
|
268
|
+
* 1. For non-logged-in users: when invite_only=true
|
|
269
|
+
* 2. For logged-in non-members: when invite_only=true AND allow_public_view_for_post=false
|
|
270
|
+
* Note: Only evaluate after membership check is complete to avoid flash
|
|
271
|
+
*/
|
|
272
|
+
const shouldRestrictPosts =
|
|
273
|
+
isInviteOnly &&
|
|
274
|
+
hasFetchedMembershipRef.current &&
|
|
275
|
+
!isLoadingMembership &&
|
|
276
|
+
(!isLoggedIn || (!isMember && !forumData?.settings?.allow_public_view_for_post));
|
|
277
|
+
|
|
278
|
+
/**
|
|
279
|
+
* Check if comments should be restricted (show overlay):
|
|
280
|
+
* 1. For non-logged-in users: when invite_only=true
|
|
281
|
+
* 2. For logged-in non-members: when invite_only=true AND allow_public_view_for_comment=false
|
|
282
|
+
* This is a secondary check - only relevant if posts are viewable
|
|
283
|
+
* Note: Only evaluate after membership check is complete to avoid flash
|
|
284
|
+
*/
|
|
285
|
+
const shouldRestrictComments =
|
|
286
|
+
isInviteOnly &&
|
|
287
|
+
hasFetchedMembershipRef.current &&
|
|
288
|
+
!isLoadingMembership &&
|
|
289
|
+
(!isLoggedIn || (!isMember && !forumData?.settings?.allow_public_view_for_comment));
|
|
290
|
+
|
|
291
|
+
/**
|
|
292
|
+
* Whether user can interact with posts (upvote/downvote):
|
|
293
|
+
* - Not invite-only: true (login modal will show if not logged in)
|
|
294
|
+
* - Invite-only + member: true
|
|
295
|
+
* - Invite-only + non-member: false (greyed out)
|
|
296
|
+
*/
|
|
297
|
+
const canInteractWithPosts = !isInviteOnly || isMember;
|
|
298
|
+
|
|
299
|
+
/**
|
|
300
|
+
* Whether user can interact with comments (reply/vote):
|
|
301
|
+
* - Not invite-only: true (login modal will show if not logged in)
|
|
302
|
+
* - Invite-only + member: true
|
|
303
|
+
* - Invite-only + non-member: false (greyed out)
|
|
304
|
+
*/
|
|
305
|
+
const canInteractWithComments = !isInviteOnly || isMember;
|
|
306
|
+
|
|
83
307
|
return (
|
|
84
|
-
<
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
<
|
|
99
|
-
|
|
100
|
-
<Box elementKey="
|
|
101
|
-
|
|
102
|
-
post={postWithVotes}
|
|
103
|
-
isRenderedSolo
|
|
104
|
-
postDetailPageBaseURL={content?.post_detail_page_url || ""}
|
|
105
|
-
actionsLoadingState={{
|
|
106
|
-
comments: isLoadingPostData,
|
|
107
|
-
}}
|
|
108
|
-
/>
|
|
109
|
-
<Comments
|
|
110
|
-
post={postWithVotes}
|
|
111
|
-
onCommentCountChange={handleCommentCountUpdate}
|
|
112
|
-
/>
|
|
113
|
-
</Box>
|
|
114
|
-
) : (
|
|
115
|
-
<Box elementKey="loading_container">
|
|
116
|
-
<Spinner className="text-brand" />
|
|
117
|
-
</Box>
|
|
118
|
-
)}
|
|
119
|
-
</Box>
|
|
120
|
-
<Box elementKey="right_container">
|
|
121
|
-
<Box elementKey="edit_profile_block">
|
|
122
|
-
<Box elementKey="edit_profile_block_content_wrapper">
|
|
123
|
-
<Media
|
|
124
|
-
elementKey="edit_profile_block_banner_image"
|
|
125
|
-
alt="Banner Image"
|
|
126
|
-
/>
|
|
127
|
-
<Box elementKey="edit_profile_block_content">
|
|
128
|
-
<Media
|
|
129
|
-
elementKey="edit_profile_block_logo"
|
|
130
|
-
alt="Community Logo"
|
|
131
|
-
/>
|
|
132
|
-
<Box elementKey="edit_profile_block_text_container">
|
|
133
|
-
<Heading elementKey="edit_profile_block_title" />
|
|
134
|
-
<Typography elementKey="edit_profile_block_description" />
|
|
135
|
-
</Box>
|
|
136
|
-
</Box>
|
|
137
|
-
</Box>
|
|
138
|
-
<Box elementKey="edit_profile_ctas_levoGroup">
|
|
139
|
-
{content?.edit_profile_ctas?.map((v, index) => {
|
|
308
|
+
<ForumProvider
|
|
309
|
+
forum={forumData}
|
|
310
|
+
isMember={isMember}
|
|
311
|
+
isLoadingMembership={isLoadingMembership}
|
|
312
|
+
isInviteOnly={isInviteOnly}
|
|
313
|
+
canInteractWithPosts={canInteractWithPosts}
|
|
314
|
+
canInteractWithComments={canInteractWithComments}
|
|
315
|
+
joinRequest={joinRequest}
|
|
316
|
+
isJoinRequestPending={!!joinRequest}
|
|
317
|
+
allowJoinRequests={allowJoinRequests}
|
|
318
|
+
submitJoinRequest={handleSubmitJoinRequest}
|
|
319
|
+
refreshMembershipStatus={checkMembership}
|
|
320
|
+
>
|
|
321
|
+
<Section elementKey="layout">
|
|
322
|
+
<Container elementKey="container">
|
|
323
|
+
<Box elementKey="left_container">
|
|
324
|
+
<Box elementKey="sidebar_links_levoGroup">
|
|
325
|
+
{content?.sidebar_links?.map((v, index) => {
|
|
140
326
|
return (
|
|
141
327
|
<Button
|
|
142
|
-
key={`
|
|
143
|
-
elementKey={`
|
|
328
|
+
key={`sidebar_links.${index}.sidebar_link`}
|
|
329
|
+
elementKey={`sidebar_links.${index}.sidebar_link`}
|
|
144
330
|
/>
|
|
145
331
|
);
|
|
146
332
|
})}
|
|
147
333
|
</Box>
|
|
148
334
|
</Box>
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
335
|
+
<Box elementKey="content_container">
|
|
336
|
+
{isInitialLoading ? (
|
|
337
|
+
<Box elementKey="loading_container">
|
|
338
|
+
<PostDetailSkeleton />
|
|
339
|
+
</Box>
|
|
340
|
+
) : shouldRestrictPosts ? (
|
|
341
|
+
<>
|
|
342
|
+
{/* Show sample posts behind the overlay */}
|
|
343
|
+
<SamplePostSkeleton opacity={0.6} />
|
|
344
|
+
<SamplePostSkeleton opacity={0.4} />
|
|
345
|
+
<SamplePostSkeleton opacity={0.3} />
|
|
346
|
+
<PostsRestrictionOverlay isOpen communityName={forumData?.name} />
|
|
347
|
+
</>
|
|
348
|
+
) : postWithVotes ? (
|
|
349
|
+
<Box elementKey="post_container">
|
|
350
|
+
<ForumPost
|
|
351
|
+
post={postWithVotes}
|
|
352
|
+
isRenderedSolo
|
|
353
|
+
postDetailPageBaseURL={content?.post_detail_page_url || ""}
|
|
354
|
+
forumKey={forumKey}
|
|
355
|
+
actionsLoadingState={{
|
|
356
|
+
comments: isLoadingPostData,
|
|
357
|
+
}}
|
|
358
|
+
/>
|
|
359
|
+
{shouldRestrictComments ? (
|
|
360
|
+
<CommentsRestrictionOverlay communityName={forumData?.name} />
|
|
361
|
+
) : (
|
|
362
|
+
<Comments
|
|
363
|
+
forumKey={forumKey}
|
|
364
|
+
post={postWithVotes}
|
|
365
|
+
onCommentCountChange={handleCommentCountUpdate}
|
|
366
|
+
/>
|
|
367
|
+
)}
|
|
368
|
+
</Box>
|
|
369
|
+
) : (
|
|
370
|
+
<Box elementKey="loading_container">
|
|
371
|
+
<PostDetailSkeleton />
|
|
372
|
+
</Box>
|
|
373
|
+
)}
|
|
374
|
+
</Box>
|
|
375
|
+
<Box elementKey="right_container">
|
|
376
|
+
<Box elementKey="edit_profile_block">
|
|
377
|
+
<Box elementKey="edit_profile_block_content_wrapper">
|
|
378
|
+
<Media elementKey="edit_profile_block_banner_image" alt="Banner Image" />
|
|
379
|
+
<Box elementKey="edit_profile_block_content">
|
|
380
|
+
<Media elementKey="edit_profile_block_logo" alt="Community Logo" />
|
|
381
|
+
<Box elementKey="edit_profile_block_text_container">
|
|
382
|
+
<Heading elementKey="edit_profile_block_title" />
|
|
383
|
+
<Typography elementKey="edit_profile_block_description" />
|
|
384
|
+
</Box>
|
|
385
|
+
</Box>
|
|
386
|
+
</Box>
|
|
387
|
+
<Box elementKey="edit_profile_ctas_levoGroup">
|
|
388
|
+
{content?.edit_profile_ctas?.map((v, index) => {
|
|
389
|
+
return (
|
|
390
|
+
<Button
|
|
391
|
+
key={`edit_profile_ctas.${index}.edit_profile_cta`}
|
|
392
|
+
elementKey={`edit_profile_ctas.${index}.edit_profile_cta`}
|
|
393
|
+
/>
|
|
394
|
+
);
|
|
395
|
+
})}
|
|
396
|
+
</Box>
|
|
397
|
+
</Box>
|
|
398
|
+
</Box>
|
|
399
|
+
</Container>
|
|
400
|
+
</Section>
|
|
401
|
+
</ForumProvider>
|
|
152
402
|
);
|
|
153
403
|
};
|
|
154
404
|
|
|
@@ -4,23 +4,15 @@ const MEDIA = {
|
|
|
4
4
|
id: "zucZWwW4cQj9F",
|
|
5
5
|
filename: "contact-us-1.png",
|
|
6
6
|
kind: "image",
|
|
7
|
-
location:
|
|
8
|
-
"https://static.levocdn.com/WLZ1TXTD/contact-us-1-OaJcGLqfj5VDC.png",
|
|
7
|
+
location: "https://static.levocdn.com/WLZ1TXTD/contact-us-1-OaJcGLqfj5VDC.png",
|
|
9
8
|
srcset: {
|
|
10
|
-
"1080w":
|
|
11
|
-
|
|
12
|
-
"
|
|
13
|
-
|
|
14
|
-
"
|
|
15
|
-
|
|
16
|
-
"
|
|
17
|
-
"https://static.levocdn.com/WLZ1TXTD/contact-us-1-OaJcGLqfj5VDC-320w.webp",
|
|
18
|
-
"640w":
|
|
19
|
-
"https://static.levocdn.com/WLZ1TXTD/contact-us-1-OaJcGLqfj5VDC-640w.webp",
|
|
20
|
-
"750w":
|
|
21
|
-
"https://static.levocdn.com/WLZ1TXTD/contact-us-1-OaJcGLqfj5VDC-750w.webp",
|
|
22
|
-
"828w":
|
|
23
|
-
"https://static.levocdn.com/WLZ1TXTD/contact-us-1-OaJcGLqfj5VDC-828w.webp",
|
|
9
|
+
"1080w": "https://static.levocdn.com/WLZ1TXTD/contact-us-1-OaJcGLqfj5VDC-1080w.webp",
|
|
10
|
+
"1200w": "https://static.levocdn.com/WLZ1TXTD/contact-us-1-OaJcGLqfj5VDC-1200w.webp",
|
|
11
|
+
"1920w": "https://static.levocdn.com/WLZ1TXTD/contact-us-1-OaJcGLqfj5VDC-1920w.webp",
|
|
12
|
+
"320w": "https://static.levocdn.com/WLZ1TXTD/contact-us-1-OaJcGLqfj5VDC-320w.webp",
|
|
13
|
+
"640w": "https://static.levocdn.com/WLZ1TXTD/contact-us-1-OaJcGLqfj5VDC-640w.webp",
|
|
14
|
+
"750w": "https://static.levocdn.com/WLZ1TXTD/contact-us-1-OaJcGLqfj5VDC-750w.webp",
|
|
15
|
+
"828w": "https://static.levocdn.com/WLZ1TXTD/contact-us-1-OaJcGLqfj5VDC-828w.webp",
|
|
24
16
|
path: "https://static.levocdn.com/WLZ1TXTD/contact-us-1-OaJcGLqfj5VDC-1920w.webp 1920w, https://static.levocdn.com/WLZ1TXTD/contact-us-1-OaJcGLqfj5VDC-320w.webp 320w, https://static.levocdn.com/WLZ1TXTD/contact-us-1-OaJcGLqfj5VDC-640w.webp 640w, https://static.levocdn.com/WLZ1TXTD/contact-us-1-OaJcGLqfj5VDC-750w.webp 750w, https://static.levocdn.com/WLZ1TXTD/contact-us-1-OaJcGLqfj5VDC-828w.webp 828w, https://static.levocdn.com/WLZ1TXTD/contact-us-1-OaJcGLqfj5VDC-1080w.webp 1080w, https://static.levocdn.com/WLZ1TXTD/contact-us-1-OaJcGLqfj5VDC-1200w.webp 1200w",
|
|
25
17
|
},
|
|
26
18
|
mimetype: "image/png",
|
|
@@ -1,19 +1,9 @@
|
|
|
1
1
|
import type { ILevoBlockBaseProps } from "@levo-so/studio";
|
|
2
|
-
import {
|
|
3
|
-
Box,
|
|
4
|
-
Button,
|
|
5
|
-
Heading,
|
|
6
|
-
Media,
|
|
7
|
-
Section,
|
|
8
|
-
Typography,
|
|
9
|
-
Container,
|
|
10
|
-
} from "@levo-so/studio";
|
|
2
|
+
import { Box, Button, Container, Heading, Media, Section, Typography } from "@levo-so/studio";
|
|
11
3
|
|
|
12
4
|
import type { IContactUs1Content } from "./contact-us-1.schema";
|
|
13
5
|
|
|
14
|
-
const ContactUs1: React.FC<ILevoBlockBaseProps<IContactUs1Content>> = ({
|
|
15
|
-
content,
|
|
16
|
-
}) => (
|
|
6
|
+
const ContactUs1: React.FC<ILevoBlockBaseProps<IContactUs1Content>> = ({ content }) => (
|
|
17
7
|
<Section elementKey="layout">
|
|
18
8
|
<Container elementKey="container">
|
|
19
9
|
<Box elementKey="contentWrapper">
|
|
@@ -1,20 +1,18 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
2
|
+
Box,
|
|
3
|
+
Container,
|
|
4
|
+
Form,
|
|
3
5
|
Heading,
|
|
4
6
|
Icon,
|
|
5
|
-
|
|
6
|
-
Container,
|
|
7
|
-
Section,
|
|
8
|
-
Box,
|
|
7
|
+
type ILevoBlockBaseProps,
|
|
9
8
|
Media,
|
|
10
|
-
|
|
9
|
+
Section,
|
|
10
|
+
Typography,
|
|
11
11
|
} from "@levo-so/studio";
|
|
12
12
|
|
|
13
13
|
import type { IContactUs2Content } from "./contact-us-2.schema";
|
|
14
14
|
|
|
15
|
-
const ContactUs2: React.FC<ILevoBlockBaseProps<IContactUs2Content>> = ({
|
|
16
|
-
content,
|
|
17
|
-
}) => (
|
|
15
|
+
const ContactUs2: React.FC<ILevoBlockBaseProps<IContactUs2Content>> = ({ content }) => (
|
|
18
16
|
<Section elementKey="layout">
|
|
19
17
|
<Container elementKey="container">
|
|
20
18
|
<Box elementKey="layoutContentWrapper">
|
|
@@ -30,32 +28,23 @@ const ContactUs2: React.FC<ILevoBlockBaseProps<IContactUs2Content>> = ({
|
|
|
30
28
|
</Box>
|
|
31
29
|
<Box data-levo_group elementKey="contact_options_levoGroup">
|
|
32
30
|
{(content?.contact_options ?? []).map((_, index) => (
|
|
33
|
-
<Box
|
|
34
|
-
data-levo_group_item
|
|
35
|
-
elementKey={`contact_options.${index}.wrapper`}
|
|
36
|
-
key={index}
|
|
37
|
-
>
|
|
31
|
+
<Box data-levo_group_item elementKey={`contact_options.${index}.wrapper`} key={index}>
|
|
38
32
|
<Icon elementKey={`contact_options.${index}.icon`} />
|
|
39
33
|
<Box elementKey={`contact_options.${index}.text_box`}>
|
|
40
34
|
<Heading elementKey={`contact_options.${index}.label`} />
|
|
41
35
|
<Typography elementKey={`contact_options.${index}.value`} />
|
|
42
|
-
<Box
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
elementKey={`contact_options.${index}.icon_links.${linkIndex}.
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
elementKey={`contact_options.${index}.icon_links.${linkIndex}.icon`}
|
|
55
|
-
/>
|
|
56
|
-
</Box>
|
|
57
|
-
),
|
|
58
|
-
)}
|
|
36
|
+
<Box data-levo_group elementKey={`contact_options.${index}.icon_links_levoGroup`}>
|
|
37
|
+
{(content?.contact_options?.[index]?.icon_links ?? []).map((_, linkIndex) => (
|
|
38
|
+
<Box
|
|
39
|
+
data-levo_group_item
|
|
40
|
+
elementKey={`contact_options.${index}.icon_links.${linkIndex}.wrapper`}
|
|
41
|
+
key={linkIndex}
|
|
42
|
+
>
|
|
43
|
+
<Icon
|
|
44
|
+
elementKey={`contact_options.${index}.icon_links.${linkIndex}.icon`}
|
|
45
|
+
/>
|
|
46
|
+
</Box>
|
|
47
|
+
))}
|
|
59
48
|
</Box>
|
|
60
49
|
</Box>
|
|
61
50
|
</Box>
|