Skip to content

Commit e4156af

Browse files
committed
Polish styles
1 parent 581230a commit e4156af

File tree

5 files changed

+206
-80
lines changed

5 files changed

+206
-80
lines changed

blocks/promotion/promotion.css

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@
7272

7373
.promotion h3 {
7474
font-size: 36px;
75+
max-width: 400px;
7576
}
7677

7778
.promotion h4 {
@@ -124,7 +125,7 @@
124125
position: relative;
125126
z-index: 1;
126127
color: #fff;
127-
max-width: 50%;
128+
max-width: 600px;
128129
padding: 4rem;
129130
margin: 0;
130131
box-sizing: border-box;

native-banner/App.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import PromoBanner from "./src/components/PromoBanner";
55
export default function App() {
66
return (
77
<SafeAreaProvider>
8-
<SafeAreaView style={{ flex: 1, backgroundColor: "#F3F4F6" }}>
8+
<SafeAreaView style={{ height: '100%', width: '100%', padding: 16}}>
99
<PromoBanner />
1010
</SafeAreaView>
1111
</SafeAreaProvider>

native-banner/src/components/PromoBanner.js

Lines changed: 81 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -2,25 +2,36 @@ import React, { useEffect, useState } from "react";
22
import {
33
View,
44
Text,
5-
Image,
65
TouchableOpacity,
76
ActivityIndicator,
87
Linking,
8+
useWindowDimensions,
9+
ScrollView,
10+
Image,
11+
ImageBackground,
912
} from "react-native";
1013
import { fetchPromoBannerData } from "../api/fetchPromoBanner";
1114
import { parsePromoBannerData } from "../utils/parsePromoBanner";
1215
import styles from "../styles/promoBannerStyles";
16+
import { EDGE_SITE } from "../config/env";
1317

1418
export default function PromoBanner() {
1519
const [banner, setBanner] = useState(null);
1620
const [loading, setLoading] = useState(true);
21+
const { width } = useWindowDimensions();
22+
const isDesktop = width >= 900;
1723

1824
useEffect(() => {
1925
async function loadBanner() {
20-
const rawData = await fetchPromoBannerData();
21-
const parsed = parsePromoBannerData(rawData);
22-
setBanner(parsed);
23-
setLoading(false);
26+
try {
27+
const rawData = await fetchPromoBannerData();
28+
const parsed = parsePromoBannerData(rawData);
29+
setBanner(parsed);
30+
} catch (e) {
31+
console.error("Failed to load banner:", e);
32+
} finally {
33+
setLoading(false);
34+
}
2435
}
2536
loadBanner();
2637
}, []);
@@ -36,44 +47,77 @@ export default function PromoBanner() {
3647
if (!banner) return null;
3748

3849
return (
39-
<View style={styles.banner}>
40-
{banner.image && (
41-
<Image
42-
source={{ uri: banner.image }}
43-
style={styles.image}
44-
resizeMode="cover"
45-
/>
46-
)}
50+
<View style={[styles.promotion, isDesktop && styles.promotionDesktop]}>
51+
<ImageBackground
52+
source={{ uri: `${EDGE_SITE}${banner.image}` }}
53+
style={[styles.imageBackground, isDesktop && styles.imageBackgroundDesktop]}
54+
imageStyle={[styles.image, isDesktop && styles.imageDesktop]}
55+
>
56+
{banner.image && (
57+
<Image
58+
source={{ uri: `${EDGE_SITE}${banner.image}` }}
59+
style={[styles.imageMobile, isDesktop && styles.imageMobileDesktop]}
60+
></Image>
61+
)}
62+
63+
<ScrollView
64+
contentContainerStyle={[
65+
styles.contentContainer,
66+
isDesktop && styles.contentContainerDesktop,
67+
]}
68+
showsVerticalScrollIndicator={false}
69+
>
70+
71+
{banner.heading && (
72+
<Text style={[styles.h3, isDesktop && styles.h3Desktop]}>
73+
{banner.heading}
74+
</Text>
75+
)}
4776

48-
<View style={styles.textContainer}>
49-
<Text style={styles.heading}>{banner.heading}</Text>
77+
{banner.listItems?.length > 0 && (
78+
<View style={styles.ul}>
79+
{banner.listItems.map((item, i) => (
80+
<Text key={i} style={[styles.h4, isDesktop && styles.h4Desktop]}>
81+
{item.text}
82+
</Text>
83+
))}
84+
</View>
85+
)}
5086

51-
{banner.listItems.map((item, i) => (
52-
<Text key={i} style={styles.listItem}>
53-
{item.text}
54-
</Text>
55-
))}
87+
{banner.price && (
88+
<Text style={[styles.h2, isDesktop && styles.h2Desktop]}>
89+
{banner.price}
90+
<Text style={styles.h2Sub}>
91+
{banner.priceSub}
92+
</Text>
93+
</Text>
94+
)}
5695

57-
<Text style={styles.price}>{banner.price}</Text>
96+
<View style={styles.linkGroup}>
97+
{banner.shopOfferLink && (
98+
<TouchableOpacity onPress={() => Linking.openURL(banner.shopOfferLink)}>
99+
<Text style={[styles.primaryButton, isDesktop && styles.primaryButtonDesktop]}>
100+
{banner.shopOfferText}
101+
</Text>
102+
</TouchableOpacity>
103+
)}
58104

59-
<View style={styles.links}>
60-
<TouchableOpacity
61-
onPress={() => Linking.openURL(banner.shopOfferLink)}
62-
>
63-
<Text style={styles.link}>{banner.shopOfferText}</Text>
64-
</TouchableOpacity>
105+
{banner.otherInfoLink && (
106+
<TouchableOpacity onPress={() => Linking.openURL(banner.otherInfoLink)}>
107+
<Text style={[styles.secondaryLink, isDesktop && styles.secondaryLinkDesktop]}>
108+
{banner.otherInfoText}
109+
</Text>
110+
</TouchableOpacity>
111+
)}
112+
</View>
65113

66-
{banner.otherInfoLink && (
67-
<TouchableOpacity
68-
onPress={() => Linking.openURL(banner.otherInfoLink)}
69-
>
70-
<Text style={styles.link}> {banner.otherInfoText}</Text>
71-
</TouchableOpacity>
114+
{banner.finePrint && (
115+
<Text style={[styles.finePrint, isDesktop && styles.finePrintDesktop]}>
116+
{banner.finePrint}
117+
</Text>
72118
)}
73-
</View>
74-
75-
<Text style={styles.finePrint}>{banner.finePrint}</Text>
76-
</View>
119+
</ScrollView>
120+
</ImageBackground>
77121
</View>
78122
);
79123
}

native-banner/src/config/env.js

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

native-banner/src/styles/promoBannerStyles.js

Lines changed: 121 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,66 +1,146 @@
1-
// src/styles/bannerStyles.js
21
import { StyleSheet } from "react-native";
32

43
export default StyleSheet.create({
5-
banner: {
6-
backgroundColor: "#fff",
7-
borderRadius: 12,
8-
padding: 16,
9-
margin: 20,
10-
elevation: 3,
11-
shadowColor: "#000",
12-
shadowOpacity: 0.1,
13-
shadowRadius: 4,
14-
flexDirection: "column",
4+
/* Container */
5+
promotion: {
6+
overflow: "hidden",
7+
maxWidth: 1440,
8+
height: '100%',
9+
width: '100%',
10+
marginVertical: 0,
11+
marginHorizontal: "auto",
12+
},
13+
promotionDesktop: {
1514
position: "relative",
1615
},
16+
17+
/* Image background */
18+
imageBackground: {
19+
width: "100%",
20+
height: "fit-content", // ensures visible area
21+
justifyContent: "flex-end",
22+
},
23+
imageBackgroundDesktop: {
24+
flex: 1,
25+
position: "absolute",
26+
top: 0,
27+
left: 0,
28+
right: 0,
29+
bottom: 0,
30+
zIndex: 0,
31+
},
1732
image: {
1833
width: "100%",
19-
height: 150,
34+
height: "100%",
35+
resizeMode: "cover",
2036
borderRadius: 8,
21-
marginBottom: 12,
2237
},
23-
textContainer: {
24-
flex: 1,
38+
imageDesktop: {
39+
resizeMode: "cover",
2540
},
26-
heading: {
27-
fontSize: 18,
28-
fontWeight: "700",
29-
marginBottom: 8,
41+
imageMobile: {
42+
display: 'block',
43+
height: 200,
44+
borderRadius: 8,
45+
},
46+
imageMobileDesktop: {
47+
display: 'none',
48+
},
49+
50+
/* Content container */
51+
contentContainer: {
52+
backgroundColor: "#f6f6f9",
53+
padding: 24,
3054
},
31-
listItem: {
32-
fontSize: 14,
33-
color: "#374151",
55+
contentContainerDesktop: {
56+
backgroundColor: "transparent",
57+
maxWidth: 625,
58+
padding: 64,
59+
zIndex: 1,
3460
},
35-
price: {
61+
62+
/* Text */
63+
h3: {
64+
fontSize: 36,
65+
color: "#000",
66+
fontWeight: "bold",
67+
marginBottom: 16,
68+
maxWidth: 400,
69+
},
70+
h3Desktop: {
71+
color: "#fff",
72+
},
73+
74+
ul: {
75+
paddingLeft: 16,
76+
marginBottom: 16,
77+
},
78+
h4: {
3679
fontSize: 20,
37-
fontWeight: "800",
38-
color: "#007AFF",
39-
marginVertical: 8,
80+
color: "#000",
81+
lineHeight: 24,
82+
marginBottom: 4,
83+
fontWeight: "bold",
84+
},
85+
h4Desktop: {
86+
color: "#fff",
87+
},
88+
89+
h2: {
90+
fontSize: 60,
91+
fontWeight: "900",
92+
color: "#000",
93+
paddingVertical: 16,
4094
},
41-
links: {
95+
h2Desktop: {
96+
color: "#fff",
97+
fontSize: 48,
98+
},
99+
h2Sub: {
100+
fontSize: 24,
101+
fontWeight: "400",
102+
paddingLeft: 10,
103+
},
104+
105+
linkGroup: {
42106
flexDirection: "row",
107+
alignItems: "center",
43108
flexWrap: "wrap",
44-
marginBottom: 6,
109+
gap: 24,
110+
marginBottom: 16,
111+
marginTop: 16,
45112
},
46-
link: {
47-
color: "#007AFF",
48-
fontWeight: "600",
113+
primaryButton: {
114+
color: "#fff",
115+
backgroundColor: "#000",
116+
borderRadius: 4,
117+
paddingVertical: 14,
118+
paddingHorizontal: 28,
119+
fontSize: 16,
120+
fontWeight: "bold",
49121
},
122+
primaryButtonDesktop: {
123+
color: "#000",
124+
backgroundColor: "rgb(246,246,249)",
125+
},
126+
secondaryLink: {
127+
color: "#000",
128+
fontSize: 16,
129+
},
130+
secondaryLinkDesktop: {
131+
color: "#fff",
132+
},
133+
50134
finePrint: {
51135
fontSize: 12,
52-
color: "#6B7280",
136+
color: "#000",
137+
marginTop: 12,
53138
},
54-
closeBtn: {
55-
position: "absolute",
56-
top: 8,
57-
right: 8,
58-
padding: 4,
59-
},
60-
closeText: {
61-
fontSize: 18,
62-
color: "#9CA3AF",
139+
finePrintDesktop: {
140+
color: "#fff",
63141
},
142+
143+
/* Loader */
64144
center: {
65145
flex: 1,
66146
justifyContent: "center",

0 commit comments

Comments
 (0)