@nuskin/routine-feature 1.0.0 → 2.0.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.
- package/lib/commonjs/RoutineDetails.js +326 -0
- package/lib/commonjs/RoutineDetails.js.map +1 -0
- package/lib/commonjs/helpers/Accessibility.js +17 -0
- package/lib/commonjs/helpers/Accessibility.js.map +1 -0
- package/lib/commonjs/index.js +222 -152
- package/lib/commonjs/index.js.map +1 -1
- package/lib/module/RoutineDetails.js +318 -0
- package/lib/module/RoutineDetails.js.map +1 -0
- package/lib/module/helpers/Accessibility.js +11 -0
- package/lib/module/helpers/Accessibility.js.map +1 -0
- package/lib/module/index.js +222 -147
- package/lib/module/index.js.map +1 -1
- package/lib/typescript/RoutineDetails.d.ts +3 -0
- package/lib/typescript/helpers/Accessibility.d.ts +9 -0
- package/lib/typescript/index.d.ts +3 -3
- package/package.json +13 -12
- package/src/RoutineDetails.tsx +346 -0
- package/src/helpers/Accessibility.tsx +7 -0
- package/src/index.tsx +230 -141
package/src/index.tsx
CHANGED
|
@@ -1,160 +1,201 @@
|
|
|
1
|
-
import React, { useEffect } from 'react';
|
|
1
|
+
import React, { useEffect, useState } from 'react';
|
|
2
2
|
import {
|
|
3
3
|
FlatList,
|
|
4
4
|
Image,
|
|
5
5
|
SafeAreaView,
|
|
6
|
-
SectionList,
|
|
7
6
|
StyleSheet,
|
|
8
7
|
Text,
|
|
9
8
|
TouchableOpacity,
|
|
10
9
|
View,
|
|
10
|
+
ActivityIndicator,
|
|
11
11
|
} from 'react-native';
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
{
|
|
28
|
-
key: '2',
|
|
29
|
-
text: 'Card Title 2',
|
|
30
|
-
uri: 'https://picsum.photos/id/10/200',
|
|
31
|
-
},
|
|
32
|
-
|
|
33
|
-
{
|
|
34
|
-
key: '3',
|
|
35
|
-
text: 'Card Title 3',
|
|
36
|
-
uri: 'https://picsum.photos/id/1002/200',
|
|
37
|
-
},
|
|
38
|
-
],
|
|
39
|
-
},
|
|
40
|
-
{
|
|
41
|
-
title: 'Featured Routines',
|
|
42
|
-
horizontal: true,
|
|
43
|
-
data: [
|
|
44
|
-
{
|
|
45
|
-
key: '1',
|
|
46
|
-
text: 'Card Title 1',
|
|
47
|
-
uri: 'https://picsum.photos/id/1011/200',
|
|
48
|
-
},
|
|
49
|
-
{
|
|
50
|
-
key: '2',
|
|
51
|
-
text: 'Card Title 2',
|
|
52
|
-
uri: 'https://picsum.photos/id/1012/200',
|
|
53
|
-
},
|
|
54
|
-
|
|
55
|
-
{
|
|
56
|
-
key: '3',
|
|
57
|
-
text: 'Card Title 3',
|
|
58
|
-
uri: 'https://picsum.photos/id/1013/200',
|
|
59
|
-
},
|
|
60
|
-
],
|
|
61
|
-
},
|
|
62
|
-
{
|
|
63
|
-
title: 'Suggested Routines',
|
|
64
|
-
horizontal: true,
|
|
65
|
-
data: [
|
|
66
|
-
{
|
|
67
|
-
key: '1',
|
|
68
|
-
text: 'Card Title 1',
|
|
69
|
-
uri: 'https://picsum.photos/id/1020/200',
|
|
70
|
-
},
|
|
71
|
-
{
|
|
72
|
-
key: '2',
|
|
73
|
-
text: 'Card Title 2',
|
|
74
|
-
uri: 'https://picsum.photos/id/1024/200',
|
|
75
|
-
},
|
|
12
|
+
import { gql, useQuery } from '@apollo/client';
|
|
13
|
+
import { useNavigation } from '@react-navigation/native';
|
|
14
|
+
import {
|
|
15
|
+
VeraHeader,
|
|
16
|
+
Logo,
|
|
17
|
+
HeaderCart,
|
|
18
|
+
colors,
|
|
19
|
+
ErrorScreen,
|
|
20
|
+
} from '@ns/mobile-ui';
|
|
21
|
+
import { localization, localizationState } from '@nuskin/utils-module';
|
|
22
|
+
import { useSnapshot } from 'valtio';
|
|
23
|
+
import RoutineDetails from './RoutineDetails';
|
|
24
|
+
import { Logger } from '@nuskin/mobile-logging';
|
|
25
|
+
import { accessibility } from './helpers/Accessibility';
|
|
26
|
+
import { createStackNavigator } from '@react-navigation/stack';
|
|
76
27
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
28
|
+
const Stack = createStackNavigator();
|
|
29
|
+
export const FETCH_ROUTINES_PAGE = gql`
|
|
30
|
+
query fetchAllHomePages($locale: String) {
|
|
31
|
+
result: all_routine(fallback_locale: true, locale: $locale) {
|
|
32
|
+
items {
|
|
33
|
+
products_used_label
|
|
34
|
+
sort_list_label
|
|
35
|
+
title
|
|
36
|
+
routines {
|
|
37
|
+
products {
|
|
38
|
+
product_name
|
|
39
|
+
product_category
|
|
40
|
+
product_imageConnection {
|
|
41
|
+
edges {
|
|
42
|
+
node {
|
|
43
|
+
url
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
products_used_label
|
|
49
|
+
routine_title
|
|
50
|
+
routines_description
|
|
51
|
+
routine_step_label
|
|
52
|
+
routine_imageConnection {
|
|
53
|
+
edges {
|
|
54
|
+
node {
|
|
55
|
+
url
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
steps {
|
|
60
|
+
imageConnection {
|
|
61
|
+
edges {
|
|
62
|
+
node {
|
|
63
|
+
url
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
step_sub_description
|
|
68
|
+
step_title
|
|
69
|
+
step_description
|
|
70
|
+
style
|
|
71
|
+
image_title
|
|
72
|
+
image_description
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
`;
|
|
85
79
|
|
|
86
|
-
const ListItem = ({ item
|
|
80
|
+
const ListItem = ({ item }) => {
|
|
81
|
+
const navigation = useNavigation();
|
|
82
|
+
const handleOnPress = () => {
|
|
83
|
+
navigation.navigate('RoutineDetails' as never, item as never);
|
|
84
|
+
};
|
|
87
85
|
return (
|
|
88
|
-
<View style={
|
|
89
|
-
<
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
86
|
+
<View style={styles.itemContainer}>
|
|
87
|
+
<TouchableOpacity onPress={handleOnPress}>
|
|
88
|
+
<View>
|
|
89
|
+
<Image
|
|
90
|
+
source={{
|
|
91
|
+
uri: item.routine_imageConnection?.edges[0]?.node?.url,
|
|
92
|
+
}}
|
|
93
|
+
style={styles.itemPhoto}
|
|
94
|
+
/>
|
|
95
|
+
</View>
|
|
96
|
+
<View style={styles.itemTextContainer}>
|
|
97
|
+
<View style={styles.itemTitleContainer}>
|
|
98
|
+
<Text style={styles.itemTextTitle}>{item.routine_title}</Text>
|
|
99
|
+
<Text style={styles.itemTextSteps}>
|
|
100
|
+
{item.steps.length} {item.routine_step_label}
|
|
101
|
+
</Text>
|
|
102
|
+
</View>
|
|
103
|
+
<View style={styles.listContainer}>
|
|
104
|
+
<Text style={styles.itemText}>{item.products_used_label}</Text>
|
|
105
|
+
<FlatList
|
|
106
|
+
data={item.products}
|
|
107
|
+
horizontal
|
|
108
|
+
renderItem={({ item, index }) => (
|
|
109
|
+
<Image
|
|
110
|
+
key={index}
|
|
111
|
+
source={{
|
|
112
|
+
uri: item.product_imageConnection?.edges[0]?.node?.url,
|
|
113
|
+
}}
|
|
114
|
+
style={styles.productPhoto}
|
|
115
|
+
resizeMode="contain"
|
|
116
|
+
/>
|
|
117
|
+
)}
|
|
118
|
+
showsHorizontalScrollIndicator={false}
|
|
119
|
+
/>
|
|
120
|
+
</View>
|
|
121
|
+
</View>
|
|
122
|
+
</TouchableOpacity>
|
|
97
123
|
</View>
|
|
98
124
|
);
|
|
99
125
|
};
|
|
100
126
|
|
|
101
127
|
const Routines = () => {
|
|
102
|
-
const
|
|
103
|
-
|
|
104
|
-
|
|
128
|
+
const localizationStore = useSnapshot(localizationState);
|
|
129
|
+
const [refresh, setRefresh] = useState(false);
|
|
130
|
+
const locale = localization.getLocalization(
|
|
131
|
+
localization.LocalizationFormat.CONTENT_STACK
|
|
132
|
+
);
|
|
133
|
+
|
|
134
|
+
const { loading, error, data, refetch } = useQuery(FETCH_ROUTINES_PAGE, {
|
|
135
|
+
variables: { locale },
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
useEffect(() => {
|
|
139
|
+
setRefresh(!refresh);
|
|
140
|
+
}, [localizationStore]);
|
|
141
|
+
|
|
142
|
+
const routinesPageData = data ? data.result.items[0] : {};
|
|
143
|
+
if (error || !routinesPageData) {
|
|
144
|
+
const errorCode = error?.graphQLErrors[0]?.extensions?.errors[0]?.code;
|
|
145
|
+
|
|
146
|
+
return (
|
|
147
|
+
<SafeAreaView style={styles.container}>
|
|
148
|
+
<ErrorScreen errorCode={errorCode} refresh={() => refetch()} />
|
|
149
|
+
</SafeAreaView>
|
|
150
|
+
);
|
|
151
|
+
}
|
|
152
|
+
if (loading) {
|
|
153
|
+
return (
|
|
154
|
+
<SafeAreaView
|
|
155
|
+
style={styles.container}
|
|
156
|
+
{...accessibility('routine-container-loading')}
|
|
157
|
+
>
|
|
158
|
+
<ActivityIndicator
|
|
159
|
+
size="large"
|
|
160
|
+
{...accessibility('routine-activity-indicator')}
|
|
161
|
+
/>
|
|
162
|
+
</SafeAreaView>
|
|
163
|
+
);
|
|
164
|
+
}
|
|
105
165
|
|
|
106
166
|
return (
|
|
107
167
|
<SafeAreaView style={styles.container} testID="routineStack">
|
|
108
168
|
<VeraHeader
|
|
109
169
|
left={<Logo accessibilityLabel="logo" />}
|
|
110
170
|
right={<HeaderCart accessibilityLabel="crt-btn" />}
|
|
111
|
-
title=
|
|
112
|
-
|
|
171
|
+
title={routinesPageData.title}
|
|
172
|
+
{...accessibility('routine-activity-indicator')}
|
|
113
173
|
/>
|
|
114
|
-
<View style={
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
contentContainerStyle={{ paddingHorizontal: 15 }}
|
|
131
|
-
/>
|
|
132
|
-
</>
|
|
133
|
-
)}
|
|
134
|
-
renderItem={({ item, section, index }) => {
|
|
135
|
-
if (section.horizontal) {
|
|
136
|
-
return null;
|
|
137
|
-
}
|
|
138
|
-
return <ListItem item={item} index={index} />;
|
|
139
|
-
}}
|
|
140
|
-
/>
|
|
174
|
+
<View style={styles.routinesContainer}>
|
|
175
|
+
{routinesPageData && (
|
|
176
|
+
<>
|
|
177
|
+
<Text style={styles.sortListText}>
|
|
178
|
+
{routinesPageData.sort_list_label}
|
|
179
|
+
</Text>
|
|
180
|
+
<FlatList
|
|
181
|
+
data={routinesPageData.routines}
|
|
182
|
+
renderItem={({ item, index }) => (
|
|
183
|
+
<ListItem item={item} key={index} />
|
|
184
|
+
)}
|
|
185
|
+
showsHorizontalScrollIndicator={false}
|
|
186
|
+
contentContainerStyle={{ paddingHorizontal: 15 }}
|
|
187
|
+
/>
|
|
188
|
+
</>
|
|
189
|
+
)}
|
|
141
190
|
</View>
|
|
142
191
|
</SafeAreaView>
|
|
143
192
|
);
|
|
144
193
|
};
|
|
145
194
|
|
|
146
|
-
function
|
|
147
|
-
return (
|
|
148
|
-
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
|
|
149
|
-
<Text>Routine</Text>
|
|
150
|
-
</View>
|
|
151
|
-
);
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
function RoutineStack(LOG, { navigation }) {
|
|
195
|
+
function RoutineStack({ navigation }) {
|
|
155
196
|
useEffect(() => {
|
|
156
197
|
const unsubscribe = navigation.addListener('focus', () => {
|
|
157
|
-
|
|
198
|
+
Logger.info('User navigated to the RoutineStack page.');
|
|
158
199
|
});
|
|
159
200
|
return unsubscribe;
|
|
160
201
|
}, [navigation]);
|
|
@@ -175,20 +216,25 @@ function RoutineStack(LOG, { navigation }) {
|
|
|
175
216
|
);
|
|
176
217
|
}
|
|
177
218
|
|
|
178
|
-
function useRoutine() {
|
|
179
|
-
//
|
|
180
|
-
}
|
|
181
|
-
|
|
182
219
|
const styles = StyleSheet.create({
|
|
183
220
|
container: {
|
|
184
221
|
flex: 1,
|
|
185
|
-
backgroundColor:
|
|
222
|
+
backgroundColor: colors.white,
|
|
223
|
+
},
|
|
224
|
+
routinesContainer: {
|
|
225
|
+
backgroundColor: colors.primaryGray,
|
|
226
|
+
flex: 1,
|
|
227
|
+
paddingTop: 10,
|
|
228
|
+
},
|
|
229
|
+
listContainer: {
|
|
230
|
+
flexDirection: 'column',
|
|
231
|
+
paddingHorizontal: 15,
|
|
232
|
+
paddingVertical: 10,
|
|
186
233
|
},
|
|
187
234
|
sectionHeader: {
|
|
188
235
|
textTransform: 'uppercase',
|
|
189
236
|
fontWeight: '600',
|
|
190
237
|
fontSize: 14,
|
|
191
|
-
// color: '#f4f4f4',
|
|
192
238
|
marginTop: 20,
|
|
193
239
|
paddingHorizontal: 15,
|
|
194
240
|
marginBottom: 5,
|
|
@@ -197,19 +243,62 @@ const styles = StyleSheet.create({
|
|
|
197
243
|
margin: 10,
|
|
198
244
|
borderRadius: 14,
|
|
199
245
|
},
|
|
246
|
+
itemContainer: {
|
|
247
|
+
backgroundColor: 'transparent',
|
|
248
|
+
flex: 1,
|
|
249
|
+
marginBottom: 10,
|
|
250
|
+
},
|
|
251
|
+
itemTextContainer: {
|
|
252
|
+
backgroundColor: colors.white,
|
|
253
|
+
paddingTop: 20,
|
|
254
|
+
paddingBottom: 10,
|
|
255
|
+
},
|
|
200
256
|
itemPhoto: {
|
|
201
|
-
width:
|
|
202
|
-
|
|
203
|
-
|
|
257
|
+
width: '100%',
|
|
258
|
+
minHeight: 160,
|
|
259
|
+
},
|
|
260
|
+
productPhoto: {
|
|
261
|
+
margin: 2,
|
|
262
|
+
width: 40,
|
|
263
|
+
height: 40,
|
|
264
|
+
borderRadius: 50,
|
|
265
|
+
borderColor: '#EDEDED',
|
|
266
|
+
borderStyle: 'solid',
|
|
267
|
+
borderWidth: 1,
|
|
268
|
+
},
|
|
269
|
+
itemTitleContainer: {
|
|
270
|
+
flexDirection: 'row',
|
|
271
|
+
justifyContent: 'space-between',
|
|
272
|
+
paddingHorizontal: 15,
|
|
273
|
+
},
|
|
274
|
+
itemTextTitle: {
|
|
275
|
+
color: colors.primaryBlack,
|
|
276
|
+
fontWeight: '600',
|
|
277
|
+
fontSize: 18,
|
|
204
278
|
},
|
|
205
279
|
itemText: {
|
|
206
|
-
color:
|
|
280
|
+
color: colors.primaryBlack,
|
|
207
281
|
fontWeight: 'bold',
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
282
|
+
fontSize: 12,
|
|
283
|
+
letterSpacing: 0.05,
|
|
284
|
+
paddingBottom: 5,
|
|
285
|
+
textTransform: 'uppercase',
|
|
286
|
+
},
|
|
287
|
+
itemTextSteps: {
|
|
288
|
+
color: colors.primaryBlack,
|
|
289
|
+
fontWeight: 'bold',
|
|
290
|
+
textTransform: 'uppercase',
|
|
291
|
+
},
|
|
292
|
+
sortListText: {
|
|
293
|
+
color: colors.primaryBlack,
|
|
294
|
+
fontWeight: 'bold',
|
|
295
|
+
textTransform: 'uppercase',
|
|
296
|
+
textAlign: 'right',
|
|
297
|
+
marginRight: 10,
|
|
298
|
+
letterSpacing: 0.5,
|
|
299
|
+
paddingVertical: 10,
|
|
300
|
+
paddingRight: 20,
|
|
212
301
|
},
|
|
213
302
|
});
|
|
214
303
|
|
|
215
|
-
export { RoutineStack
|
|
304
|
+
export { RoutineStack };
|