Browse Source

Render services in sections

Arnaud Vergnet 4 years ago
parent
commit
bbe343da3b

+ 27
- 21
src/components/Lists/CardList/CardList.js View File

@@ -1,11 +1,12 @@
1 1
 // @flow
2 2
 
3 3
 import * as React from 'react';
4
-import {Animated, View} from "react-native";
4
+import {Animated} from "react-native";
5 5
 import CardListItem from "./CardListItem";
6 6
 
7 7
 type Props = {
8
-    dataset: Array<cards>
8
+    dataset: Array<cardItem>,
9
+    isHorizontal: boolean,
9 10
 }
10 11
 
11 12
 export type cardItem = {
@@ -15,41 +16,46 @@ export type cardItem = {
15 16
     onPress: () => void,
16 17
 };
17 18
 
18
-export type cards = Array<cardItem>;
19
+export type cardList = Array<cardItem>;
19 20
 
20 21
 
21 22
 export default class CardList extends React.Component<Props> {
22 23
 
23
-    renderItem = ({item}: { item: cards }) => {
24
-        let width = '80%';
25
-        if (item.length > 1) {
26
-            width = '40%';
27
-        }
24
+    static defaultProps = {
25
+        isHorizontal: false,
26
+    }
27
+
28
+    renderItem = ({item}: { item: cardItem }) => {
28 29
         return (
29
-            <View style={{
30
-                flex: 1,
31
-                flexDirection: 'row',
32
-                justifyContent: "space-evenly",
33
-                marginTop: 10,
34
-            }}>
35
-                {item.map((card: cardItem, index: number) => {
36
-                    return (
37
-                        <CardListItem width={width} item={card} key={index.toString()}/>
38
-                    );
39
-                })}
40
-            </View>
30
+            <CardListItem width={150} item={item} key={item.title}/>
41 31
         );
42 32
     };
43 33
 
44
-    keyExtractor = (item: cards) => item[0].title;
34
+    keyExtractor = (item: cardItem) => item.title;
45 35
 
46 36
     render() {
37
+        let containerStyle = {
38
+            ...this.props.contentContainerStyle,
39
+            height: 200,
40
+            justifyContent: 'space-around',
41
+        };
42
+        if (!this.props.isHorizontal) {
43
+            containerStyle = {
44
+                ...containerStyle,
45
+                marginLeft: 'auto',
46
+                marginRight: 'auto',
47
+                height: 'auto',
48
+            }
49
+        }
47 50
         return (
48 51
             <Animated.FlatList
49 52
                 {...this.props}
50 53
                 data={this.props.dataset}
51 54
                 renderItem={this.renderItem}
52 55
                 keyExtractor={this.keyExtractor}
56
+                numColumns={this.props.isHorizontal ? undefined : 2}
57
+                horizontal={this.props.isHorizontal}
58
+                contentContainerStyle={containerStyle}
53 59
             />
54 60
         );
55 61
     }

+ 2
- 0
src/components/Lists/CardList/CardListItem.js View File

@@ -25,6 +25,8 @@ export default class CardListItem extends React.Component<Props> {
25 25
             <Card
26 26
                 style={{
27 27
                     width: props.width,
28
+                    margin: 5,
29
+                    elevation: 3,
28 30
                 }}
29 31
                 onPress={item.onPress}
30 32
             >

+ 2
- 0
src/navigation/MainTabNavigator.js View File

@@ -38,6 +38,7 @@ import VoteScreen from "../screens/Amicale/VoteScreen";
38 38
 import AmicaleContactScreen from "../screens/Amicale/AmicaleContactScreen";
39 39
 import AmicaleHomeScreen from "../screens/Amicale/AmicaleHomeScreen";
40 40
 import WebsitesHomeScreen from "../screens/Services/ServicesScreen";
41
+import ServicesSectionScreen from "../screens/Services/ServicesSectionScreen";
41 42
 
42 43
 const defaultScreenOptions = {
43 44
     gestureEnabled: true,
@@ -92,6 +93,7 @@ function ServicesStackComponent() {
92 93
             screenOptions={defaultScreenOptions}
93 94
         >
94 95
             {createScreenCollapsibleStack("index", ServicesStack, WebsitesHomeScreen, i18n.t('screens.services'))}
96
+            {createScreenCollapsibleStack("services-section", ServicesStack, ServicesSectionScreen, "SECTION")}
95 97
 
96 98
             {createScreenCollapsibleStack("proximo", ServicesStack, ProximoMainScreen, "Proximo")}
97 99
             {createScreenCollapsibleStack(

+ 108
- 53
src/screens/Services/ServicesScreen.js View File

@@ -1,12 +1,14 @@
1 1
 // @flow
2 2
 
3 3
 import * as React from 'react';
4
-import type {cards} from "../../components/Lists/CardList/CardList";
4
+import type {cardList} from "../../components/Lists/CardList/CardList";
5 5
 import CardList from "../../components/Lists/CardList/CardList";
6 6
 import CustomTabBar from "../../components/Tabbar/CustomTabBar";
7 7
 import {withCollapsible} from "../../utils/withCollapsible";
8 8
 import {Collapsible} from "react-navigation-collapsible";
9 9
 import {CommonActions} from "@react-navigation/native";
10
+import {Animated} from "react-native";
11
+import {Avatar, Card, List} from "react-native-paper";
10 12
 
11 13
 type Props = {
12 14
     navigation: Object,
@@ -25,57 +27,30 @@ const AMICALE_IMAGE = require("../../../assets/amicale.png");
25 27
 const EE_IMAGE = "https://etud.insa-toulouse.fr/~eeinsat/wp-content/uploads/2019/09/logo-blanc.png";
26 28
 const TUTORINSA_IMAGE = "https://www.etud.insa-toulouse.fr/~tutorinsa/public/images/logo-gray.png";
27 29
 
30
+type listItem = {
31
+    title: string,
32
+    description: string,
33
+    image: string | number,
34
+    content: cardList,
35
+}
36
+
28 37
 class ServicesScreen extends React.Component<Props> {
29 38
 
30
-    dataset: Array<cards>;
39
+    studentsDataset: cardList;
40
+    insaDataset: cardList;
41
+
42
+    finalDataset: Array<listItem>
31 43
 
32 44
     constructor(props) {
33 45
         super(props);
34 46
         const nav = props.navigation;
35
-        this.dataset = [
36
-            [
37
-                {
38
-                    title: "RU",
39
-                    subtitle: "the ru",
40
-                    image: RU_IMAGE,
41
-                    onPress: () => nav.navigate("self-menu"),
42
-                },
47
+        this.studentsDataset = [
43 48
                 {
44 49
                     title: "proximo",
45 50
                     subtitle: "proximo",
46 51
                     image: PROXIMO_IMAGE,
47 52
                     onPress: () => nav.navigate("proximo"),
48 53
                 },
49
-            ],
50
-            [
51
-                {
52
-                    title: "AVAILABLE ROOMS",
53
-                    subtitle: "ROOMS",
54
-                    image: ROOM_IMAGE,
55
-                    onPress: () => nav.navigate("available-rooms"),
56
-                },
57
-                {
58
-                    title: "BIB",
59
-                    subtitle: "BIB",
60
-                    image: BIB_IMAGE,
61
-                    onPress: () => nav.navigate("bib"),
62
-                },
63
-            ],
64
-            [
65
-                {
66
-                    title: "EMAIL",
67
-                    subtitle: "EMAIL",
68
-                    image: EMAIL_IMAGE,
69
-                    onPress: () => nav.navigate("bluemind"),
70
-                },
71
-                {
72
-                    title: "ENT",
73
-                    subtitle: "ENT",
74
-                    image: ENT_IMAGE,
75
-                    onPress: () => nav.navigate("ent"),
76
-                },
77
-            ],
78
-            [
79 54
                 {
80 55
                     title: "AMICALE",
81 56
                     subtitle: "AMICALE",
@@ -88,8 +63,6 @@ class ServicesScreen extends React.Component<Props> {
88 63
                     image: WIKETUD_LINK,
89 64
                     onPress: () => nav.navigate("wiketud"),
90 65
                 },
91
-            ],
92
-            [
93 66
                 {
94 67
                     title: "ELUS ETUDIANTS",
95 68
                     subtitle: "ELUS ETUDIANTS",
@@ -102,8 +75,53 @@ class ServicesScreen extends React.Component<Props> {
102 75
                     image: TUTORINSA_IMAGE,
103 76
                     onPress: () => nav.navigate("tutorinsa"),
104 77
                 },
105
-            ],
106 78
         ];
79
+        this.insaDataset = [
80
+                {
81
+                    title: "RU",
82
+                    subtitle: "the ru",
83
+                    image: RU_IMAGE,
84
+                    onPress: () => nav.navigate("self-menu"),
85
+                },
86
+                {
87
+                    title: "AVAILABLE ROOMS",
88
+                    subtitle: "ROOMS",
89
+                    image: ROOM_IMAGE,
90
+                    onPress: () => nav.navigate("available-rooms"),
91
+                },
92
+                {
93
+                    title: "BIB",
94
+                    subtitle: "BIB",
95
+                    image: BIB_IMAGE,
96
+                    onPress: () => nav.navigate("bib"),
97
+                },
98
+                {
99
+                    title: "EMAIL",
100
+                    subtitle: "EMAIL",
101
+                    image: EMAIL_IMAGE,
102
+                    onPress: () => nav.navigate("bluemind"),
103
+                },
104
+                {
105
+                    title: "ENT",
106
+                    subtitle: "ENT",
107
+                    image: ENT_IMAGE,
108
+                    onPress: () => nav.navigate("ent"),
109
+                },
110
+        ];
111
+        this.finalDataset = [
112
+            {
113
+                title: "AMICALE",
114
+                description: "youhou",
115
+                image: AMICALE_IMAGE,
116
+                content: this.studentsDataset
117
+            },
118
+            {
119
+                title: "INSA",
120
+                description: "youhou",
121
+                image: AMICALE_IMAGE,
122
+                content: this.insaDataset
123
+            },
124
+        ]
107 125
     }
108 126
 
109 127
     componentDidMount() {
@@ -121,19 +139,56 @@ class ServicesScreen extends React.Component<Props> {
121 139
         }
122 140
     };
123 141
 
124
-    render() {
125
-        const {containerPaddingTop, scrollIndicatorInsetTop, onScroll} = this.props.collapsibleStack;
142
+    getAvatar(props, source: string | number) {
143
+        if (typeof source === "number")
144
+        return <Avatar.Image
145
+            size={48}
146
+            source={AMICALE_IMAGE}
147
+            style={{backgroundColor: 'transparent'}}/>
148
+        else
149
+            return <List.Icon {...props} icon={source} />
150
+    }
151
+
152
+    renderItem = ({item} : {item: listItem}) => {
126 153
         return (
127
-            <CardList
128
-                dataset={this.dataset}
129
-                onScroll={onScroll}
130
-                contentContainerStyle={{
131
-                    paddingTop: containerPaddingTop,
132
-                    paddingBottom: CustomTabBar.TAB_BAR_HEIGHT + 20
154
+            <Card
155
+                style={{
156
+                    margin: 5,
133 157
                 }}
134
-                scrollIndicatorInsets={{top: scrollIndicatorInsetTop}}
135
-            />
158
+                onPress={() => this.props.navigation.navigate("services-section", {data: item})}
159
+            >
160
+                <Card.Title
161
+                    title={item.title}
162
+                    subtitle={item.description}
163
+                    left={(props) => this.getAvatar(props, item.image)}
164
+                    right={(props) => <List.Icon {...props} icon="chevron-right" />}
165
+                />
166
+                <CardList
167
+                    dataset={item.content}
168
+                    isHorizontal={true}
169
+                />
170
+            </Card>
171
+
136 172
         );
173
+    };
174
+
175
+    keyExtractor = (item: listItem) => {
176
+        return item.title;
177
+    }
178
+
179
+    render() {
180
+        const {containerPaddingTop, scrollIndicatorInsetTop, onScroll} = this.props.collapsibleStack;
181
+        return <Animated.FlatList
182
+            data={this.finalDataset}
183
+            renderItem={this.renderItem}
184
+            keyExtractor={this.keyExtractor}
185
+            onScroll={onScroll}
186
+            contentContainerStyle={{
187
+                paddingTop: containerPaddingTop,
188
+                paddingBottom: CustomTabBar.TAB_BAR_HEIGHT + 20
189
+            }}
190
+            scrollIndicatorInsets={{top: scrollIndicatorInsetTop}}
191
+        />
137 192
     }
138 193
 }
139 194
 

+ 69
- 0
src/screens/Services/ServicesSectionScreen.js View File

@@ -0,0 +1,69 @@
1
+// @flow
2
+
3
+import * as React from 'react';
4
+import type {cardList} from "../../components/Lists/CardList/CardList";
5
+import CardList from "../../components/Lists/CardList/CardList";
6
+import CustomTabBar from "../../components/Tabbar/CustomTabBar";
7
+import {withCollapsible} from "../../utils/withCollapsible";
8
+import {Collapsible} from "react-navigation-collapsible";
9
+import {CommonActions} from "@react-navigation/native";
10
+
11
+type Props = {
12
+    navigation: Object,
13
+    route: Object,
14
+    collapsibleStack: Collapsible,
15
+}
16
+const BIB_IMAGE = "https://scontent-cdg2-1.xx.fbcdn.net/v/t1.0-9/50695561_2124263197597162_2325349608210825216_n.jpg?_nc_cat=109&_nc_sid=8bfeb9&_nc_ohc=tmcV6FWO7_kAX9vfWHU&_nc_ht=scontent-cdg2-1.xx&oh=3b81c76e46b49f7c3a033ea3b07ec212&oe=5EC59B4D";
17
+const RU_IMAGE = "https://scontent-cdg2-1.xx.fbcdn.net/v/t1.0-9/47123773_2041883702501779_5289372776166064128_o.jpg?_nc_cat=100&_nc_sid=cdbe9c&_nc_ohc=dpuBGlIIy_EAX8CyC0l&_nc_ht=scontent-cdg2-1.xx&oh=5c5bb4f0c7f12b554246f7c9b620a5f3&oe=5EC4DB31";
18
+const ROOM_IMAGE = "https://scontent-cdt1-1.xx.fbcdn.net/v/t1.0-9/47041013_2043521689004647_316124496522117120_n.jpg?_nc_cat=103&_nc_sid=8bfeb9&_nc_ohc=bIp8OVJvvSEAX8mKnDZ&_nc_ht=scontent-cdt1-1.xx&oh=b4fef72a645804a849ad30e9e20fca12&oe=5EC29309";
19
+const EMAIL_IMAGE = "https://etud-mel.insa-toulouse.fr/webmail/images/logo-bluemind.png";
20
+const ENT_IMAGE = "https://ent.insa-toulouse.fr/media/org/jasig/portal/layout/tab-column/xhtml-theme/insa/institutional/LogoInsa.png";
21
+
22
+const PROXIMO_IMAGE = require("../../../assets/proximo-logo.png");
23
+const WIKETUD_LINK = "https://wiki.etud.insa-toulouse.fr/resources/assets/wiketud.png?ff051";
24
+const AMICALE_IMAGE = require("../../../assets/amicale.png");
25
+const EE_IMAGE = "https://etud.insa-toulouse.fr/~eeinsat/wp-content/uploads/2019/09/logo-blanc.png";
26
+const TUTORINSA_IMAGE = "https://www.etud.insa-toulouse.fr/~tutorinsa/public/images/logo-gray.png";
27
+
28
+type listItem = {
29
+    title: string,
30
+    description: string,
31
+    image: string | number,
32
+    content: cardList,
33
+}
34
+
35
+class ServicesSectionScreen extends React.Component<Props> {
36
+
37
+    finalDataset: listItem;
38
+
39
+    constructor(props) {
40
+        super(props);
41
+        this.handleNavigationParams();
42
+    }
43
+
44
+    handleNavigationParams() {
45
+        if (this.props.route.params != null) {
46
+            if (this.props.route.params.data != null) {
47
+                this.finalDataset = this.props.route.params.data;
48
+                // reset params to prevent infinite loop
49
+                this.props.navigation.dispatch(CommonActions.setParams({data: null}));
50
+            }
51
+        }
52
+    }
53
+
54
+    render() {
55
+        const {containerPaddingTop, scrollIndicatorInsetTop, onScroll} = this.props.collapsibleStack;
56
+        return <CardList
57
+            dataset={this.finalDataset.content}
58
+            isHorizontal={false}
59
+            onScroll={onScroll}
60
+            contentContainerStyle={{
61
+                paddingTop: containerPaddingTop,
62
+                paddingBottom: CustomTabBar.TAB_BAR_HEIGHT + 20
63
+            }}
64
+            scrollIndicatorInsets={{top: scrollIndicatorInsetTop}}
65
+        />
66
+    }
67
+}
68
+
69
+export default withCollapsible(ServicesSectionScreen);

Loading…
Cancel
Save