Compare commits
31 commits
77cc5d8746
...
ac9709d666
| Author | SHA1 | Date | |
|---|---|---|---|
| ac9709d666 | |||
| f7e66b1251 | |||
| 38a5761f23 | |||
| faa174b8f1 | |||
| 030cf7b795 | |||
| e8fc8b79dc | |||
| 62db99cac7 | |||
| 87f0c01024 | |||
| b5d2f686dd | |||
| 9207d02c2a | |||
| b31269586b | |||
| fc7754588f | |||
| 92fce1d425 | |||
| 0c71a78b22 | |||
| c9b8a6e2ca | |||
| 3f945fca7a | |||
| 49fa8a82e3 | |||
| 524dd5362a | |||
| 443f179f1d | |||
| 8eaa46b900 | |||
| 926515213d | |||
| bbe343da3b | |||
| 8fca2eac12 | |||
| 20cff1aeb1 | |||
| 96ed75ac72 | |||
| b151a8ff6f | |||
| 1f0ada3b24 | |||
| 78634b0c5d | |||
| e6835b0d6f | |||
| 03c4a43e58 | |||
| 0b17a35856 |
30 changed files with 839 additions and 839 deletions
6
App.js
6
App.js
|
|
@ -9,7 +9,7 @@ import {AppLoading} from 'expo';
|
||||||
import type {CustomTheme} from "./src/managers/ThemeManager";
|
import type {CustomTheme} from "./src/managers/ThemeManager";
|
||||||
import ThemeManager from './src/managers/ThemeManager';
|
import ThemeManager from './src/managers/ThemeManager';
|
||||||
import {NavigationContainer} from '@react-navigation/native';
|
import {NavigationContainer} from '@react-navigation/native';
|
||||||
import DrawerNavigator from './src/navigation/DrawerNavigator';
|
import MainNavigator from './src/navigation/MainNavigator';
|
||||||
import {initExpoToken} from "./src/utils/Notifications";
|
import {initExpoToken} from "./src/utils/Notifications";
|
||||||
import {Provider as PaperProvider} from 'react-native-paper';
|
import {Provider as PaperProvider} from 'react-native-paper';
|
||||||
import AprilFoolsManager from "./src/managers/AprilFoolsManager";
|
import AprilFoolsManager from "./src/managers/AprilFoolsManager";
|
||||||
|
|
@ -156,7 +156,7 @@ export default class App extends React.Component<Props, State> {
|
||||||
*/
|
*/
|
||||||
onLoadFinished() {
|
onLoadFinished() {
|
||||||
// Only show intro if this is the first time starting the app
|
// Only show intro if this is the first time starting the app
|
||||||
this.createDrawerNavigator = () => <DrawerNavigator
|
this.createDrawerNavigator = () => <MainNavigator
|
||||||
defaultHomeRoute={this.defaultHomeRoute}
|
defaultHomeRoute={this.defaultHomeRoute}
|
||||||
defaultHomeData={this.defaultHomeData}
|
defaultHomeData={this.defaultHomeData}
|
||||||
/>;
|
/>;
|
||||||
|
|
@ -191,7 +191,7 @@ export default class App extends React.Component<Props, State> {
|
||||||
return (
|
return (
|
||||||
<PaperProvider theme={this.state.currentTheme}>
|
<PaperProvider theme={this.state.currentTheme}>
|
||||||
<NavigationContainer theme={this.state.currentTheme} ref={this.navigatorRef}>
|
<NavigationContainer theme={this.state.currentTheme} ref={this.navigatorRef}>
|
||||||
<DrawerNavigator
|
<MainNavigator
|
||||||
defaultHomeRoute={this.defaultHomeRoute}
|
defaultHomeRoute={this.defaultHomeRoute}
|
||||||
defaultHomeData={this.defaultHomeData}
|
defaultHomeData={this.defaultHomeData}
|
||||||
/>
|
/>
|
||||||
|
|
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 79 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 90 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 111 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 216 KiB After Width: | Height: | Size: 147 KiB |
|
|
@ -5,36 +5,48 @@ import {Avatar, Card, List, withTheme} from 'react-native-paper';
|
||||||
import {StyleSheet} from "react-native";
|
import {StyleSheet} from "react-native";
|
||||||
import {DrawerNavigationProp} from "@react-navigation/drawer";
|
import {DrawerNavigationProp} from "@react-navigation/drawer";
|
||||||
import type {CustomTheme} from "../../managers/ThemeManager";
|
import type {CustomTheme} from "../../managers/ThemeManager";
|
||||||
|
import i18n from 'i18n-js';
|
||||||
|
|
||||||
const ICON_AMICALE = require("../../../assets/amicale.png");
|
const ICON_AMICALE = require("../../../assets/amicale.png");
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
navigation: DrawerNavigationProp,
|
navigation: DrawerNavigationProp,
|
||||||
theme: CustomTheme,
|
theme: CustomTheme,
|
||||||
|
isLoggedIn: boolean,
|
||||||
}
|
}
|
||||||
|
|
||||||
class ActionsDashBoardItem extends React.Component<Props> {
|
class ActionsDashBoardItem extends React.Component<Props> {
|
||||||
|
|
||||||
shouldComponentUpdate(nextProps: Props): boolean {
|
shouldComponentUpdate(nextProps: Props): boolean {
|
||||||
return (nextProps.theme.dark !== this.props.theme.dark)
|
return (nextProps.theme.dark !== this.props.theme.dark)
|
||||||
|
|| (nextProps.isLoggedIn !== this.props.isLoggedIn);
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
const isLoggedIn = this.props.isLoggedIn;
|
||||||
return (
|
return (
|
||||||
<Card style={{
|
<Card style={{
|
||||||
...styles.card,
|
...styles.card,
|
||||||
borderColor: this.props.theme.colors.primary,
|
borderColor: this.props.theme.colors.primary,
|
||||||
}}>
|
}}>
|
||||||
<List.Item
|
<List.Item
|
||||||
title={"AMICALE"}
|
title={i18n.t("homeScreen.dashboard.amicaleTitle")}
|
||||||
description={"VOTRE COMPTE"}
|
description={isLoggedIn
|
||||||
|
? i18n.t("homeScreen.dashboard.amicaleConnected")
|
||||||
|
: i18n.t("homeScreen.dashboard.amicaleConnect")}
|
||||||
left={props => <Avatar.Image
|
left={props => <Avatar.Image
|
||||||
{...props}
|
{...props}
|
||||||
size={40}
|
size={40}
|
||||||
source={ICON_AMICALE}
|
source={ICON_AMICALE}
|
||||||
style={styles.avatar}/>}
|
style={styles.avatar}/>}
|
||||||
right={props => <List.Icon {...props} icon="chevron-right"/>}
|
right={props => <List.Icon {...props} icon={isLoggedIn
|
||||||
onPress={() => this.props.navigation.navigate("amicale-home")}
|
? "chevron-right"
|
||||||
|
: "login"}/>}
|
||||||
|
onPress={isLoggedIn
|
||||||
|
? () => this.props.navigation.navigate("services", {
|
||||||
|
screen: 'index'
|
||||||
|
})
|
||||||
|
: () => this.props.navigation.navigate("login")}
|
||||||
style={styles.list}
|
style={styles.list}
|
||||||
/>
|
/>
|
||||||
</Card>
|
</Card>
|
||||||
|
|
@ -51,7 +63,9 @@ const styles = StyleSheet.create({
|
||||||
borderWidth: 1,
|
borderWidth: 1,
|
||||||
},
|
},
|
||||||
avatar: {
|
avatar: {
|
||||||
backgroundColor: 'transparent'
|
backgroundColor: 'transparent',
|
||||||
|
marginTop: 'auto',
|
||||||
|
marginBottom: 'auto',
|
||||||
},
|
},
|
||||||
list: {
|
list: {
|
||||||
// height: 50,
|
// height: 50,
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,6 @@ type Props = {
|
||||||
};
|
};
|
||||||
|
|
||||||
const AnimatableBadge = Animatable.createAnimatableComponent(Badge);
|
const AnimatableBadge = Animatable.createAnimatableComponent(Badge);
|
||||||
const AnimatableIconButton = Animatable.createAnimatableComponent(IconButton);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Component used to render a small dashboard item
|
* Component used to render a small dashboard item
|
||||||
|
|
@ -34,7 +33,7 @@ class SmallDashboardItem extends React.Component<Props> {
|
||||||
const colors = props.theme.colors;
|
const colors = props.theme.colors;
|
||||||
return (
|
return (
|
||||||
<View>
|
<View>
|
||||||
<AnimatableIconButton
|
<IconButton
|
||||||
icon={props.icon}
|
icon={props.icon}
|
||||||
color={
|
color={
|
||||||
props.isAvailable
|
props.isAvailable
|
||||||
|
|
|
||||||
63
src/components/Lists/CardList/CardList.js
Normal file
63
src/components/Lists/CardList/CardList.js
Normal file
|
|
@ -0,0 +1,63 @@
|
||||||
|
// @flow
|
||||||
|
|
||||||
|
import * as React from 'react';
|
||||||
|
import {Animated} from "react-native";
|
||||||
|
import ImageListItem from "./ImageListItem";
|
||||||
|
import CardListItem from "./CardListItem";
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
dataset: Array<cardItem>,
|
||||||
|
isHorizontal: boolean,
|
||||||
|
}
|
||||||
|
|
||||||
|
export type cardItem = {
|
||||||
|
title: string,
|
||||||
|
subtitle: string,
|
||||||
|
image: string | number,
|
||||||
|
onPress: () => void,
|
||||||
|
};
|
||||||
|
|
||||||
|
export type cardList = Array<cardItem>;
|
||||||
|
|
||||||
|
|
||||||
|
export default class CardList extends React.Component<Props> {
|
||||||
|
|
||||||
|
static defaultProps = {
|
||||||
|
isHorizontal: false,
|
||||||
|
}
|
||||||
|
|
||||||
|
renderItem = ({item}: { item: cardItem }) => {
|
||||||
|
if (this.props.isHorizontal)
|
||||||
|
return <ImageListItem item={item} key={item.title}/>;
|
||||||
|
else
|
||||||
|
return <CardListItem item={item} key={item.title}/>;
|
||||||
|
};
|
||||||
|
|
||||||
|
keyExtractor = (item: cardItem) => item.title;
|
||||||
|
|
||||||
|
render() {
|
||||||
|
let containerStyle;
|
||||||
|
if (this.props.isHorizontal) {
|
||||||
|
containerStyle = {
|
||||||
|
...this.props.contentContainerStyle,
|
||||||
|
height: 150,
|
||||||
|
justifyContent: 'space-around',
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
containerStyle = {
|
||||||
|
...this.props.contentContainerStyle,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<Animated.FlatList
|
||||||
|
{...this.props}
|
||||||
|
data={this.props.dataset}
|
||||||
|
renderItem={this.renderItem}
|
||||||
|
keyExtractor={this.keyExtractor}
|
||||||
|
numColumns={this.props.isHorizontal ? undefined : 2}
|
||||||
|
horizontal={this.props.isHorizontal}
|
||||||
|
contentContainerStyle={containerStyle}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
44
src/components/Lists/CardList/CardListItem.js
Normal file
44
src/components/Lists/CardList/CardListItem.js
Normal file
|
|
@ -0,0 +1,44 @@
|
||||||
|
// @flow
|
||||||
|
|
||||||
|
import * as React from 'react';
|
||||||
|
import {Caption, Card, Paragraph} from 'react-native-paper';
|
||||||
|
import type {cardItem} from "./CardList";
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
item: cardItem,
|
||||||
|
}
|
||||||
|
|
||||||
|
export default class CardListItem extends React.Component<Props> {
|
||||||
|
|
||||||
|
shouldComponentUpdate() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const props = this.props;
|
||||||
|
const item = props.item;
|
||||||
|
const source = typeof item.image === "number"
|
||||||
|
? item.image
|
||||||
|
: {uri: item.image};
|
||||||
|
return (
|
||||||
|
<Card
|
||||||
|
style={{
|
||||||
|
width: '40%',
|
||||||
|
margin: 5,
|
||||||
|
marginLeft: 'auto',
|
||||||
|
marginRight: 'auto',
|
||||||
|
}}
|
||||||
|
onPress={item.onPress}
|
||||||
|
>
|
||||||
|
<Card.Cover
|
||||||
|
style={{height: 80}}
|
||||||
|
source={source}
|
||||||
|
/>
|
||||||
|
<Card.Content>
|
||||||
|
<Paragraph>{item.title}</Paragraph>
|
||||||
|
<Caption>{item.subtitle}</Caption>
|
||||||
|
</Card.Content>
|
||||||
|
</Card>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
53
src/components/Lists/CardList/ImageListItem.js
Normal file
53
src/components/Lists/CardList/ImageListItem.js
Normal file
|
|
@ -0,0 +1,53 @@
|
||||||
|
// @flow
|
||||||
|
|
||||||
|
import * as React from 'react';
|
||||||
|
import {Text, TouchableRipple} from 'react-native-paper';
|
||||||
|
import {Image, View} from 'react-native';
|
||||||
|
import type {cardItem} from "./CardList";
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
item: cardItem,
|
||||||
|
}
|
||||||
|
|
||||||
|
export default class ImageListItem extends React.Component<Props> {
|
||||||
|
|
||||||
|
shouldComponentUpdate() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const props = this.props;
|
||||||
|
const item = props.item;
|
||||||
|
const source = typeof item.image === "number"
|
||||||
|
? item.image
|
||||||
|
: {uri: item.image};
|
||||||
|
return (
|
||||||
|
<TouchableRipple
|
||||||
|
style={{
|
||||||
|
width: 100,
|
||||||
|
height: 150,
|
||||||
|
margin: 5,
|
||||||
|
}}
|
||||||
|
onPress={item.onPress}
|
||||||
|
>
|
||||||
|
<View>
|
||||||
|
<Image
|
||||||
|
style={{
|
||||||
|
width: 80,
|
||||||
|
height: 80,
|
||||||
|
marginLeft: 'auto',
|
||||||
|
marginRight: 'auto',
|
||||||
|
}}
|
||||||
|
source={source}
|
||||||
|
/>
|
||||||
|
<Text style={{
|
||||||
|
marginTop: 5,
|
||||||
|
marginLeft: 'auto',
|
||||||
|
marginRight: 'auto',
|
||||||
|
textAlign: 'center'
|
||||||
|
}}>{item.title}</Text>
|
||||||
|
</View>
|
||||||
|
</TouchableRipple>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -6,15 +6,13 @@ import {HeaderButton, HeaderButtons} from 'react-navigation-header-buttons';
|
||||||
import {withTheme} from "react-native-paper";
|
import {withTheme} from "react-native-paper";
|
||||||
import * as Touchable from "react-native/Libraries/Components/Touchable/TouchableNativeFeedback.android";
|
import * as Touchable from "react-native/Libraries/Components/Touchable/TouchableNativeFeedback.android";
|
||||||
|
|
||||||
const MaterialHeaderButton = (props: Object) => (
|
const MaterialHeaderButton = (props: Object) => <HeaderButton
|
||||||
<HeaderButton
|
|
||||||
IconComponent={MaterialCommunityIcons}
|
IconComponent={MaterialCommunityIcons}
|
||||||
iconSize={26}
|
iconSize={26}
|
||||||
color={props.theme.colors.text}
|
color={props.color != null ? props.color : props.theme.colors.text}
|
||||||
background={Touchable.Ripple(props.theme.colors.ripple, true)}
|
background={Touchable.Ripple(props.theme.colors.ripple, true)}
|
||||||
{...props}
|
{...props}
|
||||||
/>
|
/>;
|
||||||
);
|
|
||||||
|
|
||||||
const MaterialHeaderButtons = (props: Object) => {
|
const MaterialHeaderButtons = (props: Object) => {
|
||||||
return (
|
return (
|
||||||
|
|
|
||||||
|
|
@ -1,148 +0,0 @@
|
||||||
// @flow
|
|
||||||
|
|
||||||
import * as React from 'react';
|
|
||||||
import {FlatList} from "react-native";
|
|
||||||
import {Drawer, withTheme} from 'react-native-paper';
|
|
||||||
import {Linking} from "expo";
|
|
||||||
import AnimatedAccordion from "../Animations/AnimatedAccordion";
|
|
||||||
import {StackActions} from '@react-navigation/native';
|
|
||||||
|
|
||||||
type Props = {
|
|
||||||
navigation: Object,
|
|
||||||
startOpen: boolean,
|
|
||||||
isLoggedIn: boolean,
|
|
||||||
sectionName: string,
|
|
||||||
activeRoute: string,
|
|
||||||
listKey: string,
|
|
||||||
listData: Array<Object>,
|
|
||||||
}
|
|
||||||
|
|
||||||
const LIST_ITEM_HEIGHT = 48;
|
|
||||||
|
|
||||||
class SideBarSection extends React.PureComponent<Props> {
|
|
||||||
|
|
||||||
colors: Object;
|
|
||||||
accordionRef: {current: null | AnimatedAccordion};
|
|
||||||
|
|
||||||
constructor(props) {
|
|
||||||
super(props);
|
|
||||||
this.colors = props.theme.colors;
|
|
||||||
this.accordionRef = React.createRef();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Searches if the current route is contained in the given list data.
|
|
||||||
* If this is the case and the list is collapsed, we should expand this list.
|
|
||||||
*
|
|
||||||
* @return boolean
|
|
||||||
*/
|
|
||||||
shouldExpandList() {
|
|
||||||
for (let i = 0; i < this.props.listData.length; i++) {
|
|
||||||
if (this.props.listData[i].route === this.props.activeRoute) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Callback when a drawer item is pressed.
|
|
||||||
* It will either navigate to the associated screen, or open the browser to the associated link
|
|
||||||
*
|
|
||||||
* @param item The item pressed
|
|
||||||
*/
|
|
||||||
onListItemPress(item: Object) {
|
|
||||||
if (item.link !== undefined)
|
|
||||||
Linking.openURL(item.link);
|
|
||||||
else if (item.action !== undefined)
|
|
||||||
item.action();
|
|
||||||
else if (this.props.activeRoute === "main")
|
|
||||||
this.props.navigation.navigate(item.route);
|
|
||||||
else {
|
|
||||||
this.props.navigation.dispatch(
|
|
||||||
StackActions.replace(item.route)
|
|
||||||
);
|
|
||||||
this.props.navigation.closeDrawer();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Key extractor for list items
|
|
||||||
*
|
|
||||||
* @param item The item to extract the key from
|
|
||||||
* @return {string} The extracted key
|
|
||||||
*/
|
|
||||||
listKeyExtractor = (item: Object) => item.route;
|
|
||||||
|
|
||||||
shouldHideItem(item: Object) {
|
|
||||||
const onlyWhenLoggedOut = item.onlyWhenLoggedOut !== undefined && item.onlyWhenLoggedOut === true;
|
|
||||||
const onlyWhenLoggedIn = item.onlyWhenLoggedIn !== undefined && item.onlyWhenLoggedIn === true;
|
|
||||||
return (onlyWhenLoggedIn && !this.props.isLoggedIn || onlyWhenLoggedOut && this.props.isLoggedIn);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the render item for the given list item
|
|
||||||
*
|
|
||||||
* @param item The item to render
|
|
||||||
* @return {*}
|
|
||||||
*/
|
|
||||||
getRenderItem = ({item}: Object) => {
|
|
||||||
const onListItemPress = this.onListItemPress.bind(this, item);
|
|
||||||
if (this.shouldHideItem(item))
|
|
||||||
return null;
|
|
||||||
return (
|
|
||||||
<Drawer.Item
|
|
||||||
label={item.name}
|
|
||||||
active={this.props.activeRoute === item.route}
|
|
||||||
icon={item.icon}
|
|
||||||
onPress={onListItemPress}
|
|
||||||
style={{
|
|
||||||
height: LIST_ITEM_HEIGHT,
|
|
||||||
justifyContent: 'center',
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
shouldRenderAccordion() {
|
|
||||||
let itemsToRender = 0;
|
|
||||||
for (let i = 0; i < this.props.listData.length; i++) {
|
|
||||||
if (!this.shouldHideItem(this.props.listData[i]))
|
|
||||||
itemsToRender += 1;
|
|
||||||
}
|
|
||||||
return itemsToRender > 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
itemLayout = (data, index) => ({length: LIST_ITEM_HEIGHT, offset: LIST_ITEM_HEIGHT * index, index});
|
|
||||||
|
|
||||||
getFlatList() {
|
|
||||||
return (
|
|
||||||
// $FlowFixMe
|
|
||||||
<FlatList
|
|
||||||
data={this.props.listData}
|
|
||||||
extraData={this.props.isLoggedIn.toString() + this.props.activeRoute}
|
|
||||||
renderItem={this.getRenderItem}
|
|
||||||
keyExtractor={this.listKeyExtractor}
|
|
||||||
listKey={this.props.listKey}
|
|
||||||
// Performance props, see https://reactnative.dev/docs/optimizing-flatlist-configuration
|
|
||||||
getItemLayout={this.itemLayout}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
|
||||||
if (this.shouldRenderAccordion()) {
|
|
||||||
return (
|
|
||||||
<AnimatedAccordion
|
|
||||||
title={this.props.sectionName}
|
|
||||||
keepOpen={this.shouldExpandList()}
|
|
||||||
>
|
|
||||||
{this.getFlatList()}
|
|
||||||
</AnimatedAccordion>
|
|
||||||
);
|
|
||||||
} else
|
|
||||||
return this.getFlatList();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default withTheme(SideBarSection);
|
|
||||||
|
|
@ -1,267 +0,0 @@
|
||||||
// @flow
|
|
||||||
|
|
||||||
import * as React from 'react';
|
|
||||||
import {Dimensions, FlatList, Image, StyleSheet, View,} from 'react-native';
|
|
||||||
import i18n from "i18n-js";
|
|
||||||
import {TouchableRipple} from "react-native-paper";
|
|
||||||
import ConnectionManager from "../../managers/ConnectionManager";
|
|
||||||
import LogoutDialog from "../Amicale/LogoutDialog";
|
|
||||||
import SideBarSection from "./SideBarSection";
|
|
||||||
import {DrawerNavigationProp} from "@react-navigation/drawer";
|
|
||||||
|
|
||||||
const deviceWidth = Dimensions.get("window").width;
|
|
||||||
|
|
||||||
type Props = {
|
|
||||||
navigation: DrawerNavigationProp,
|
|
||||||
state: {[key: string] : any},
|
|
||||||
theme?: Object,
|
|
||||||
};
|
|
||||||
|
|
||||||
type State = {
|
|
||||||
isLoggedIn: boolean,
|
|
||||||
dialogVisible: boolean,
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Component used to render the drawer menu content
|
|
||||||
*/
|
|
||||||
class SideBar extends React.Component<Props, State> {
|
|
||||||
|
|
||||||
dataSet: Array<Object>;
|
|
||||||
activeRoute: string;
|
|
||||||
/**
|
|
||||||
* Generate the dataset
|
|
||||||
*
|
|
||||||
* @param props
|
|
||||||
*/
|
|
||||||
constructor(props: Props) {
|
|
||||||
super(props);
|
|
||||||
this.activeRoute = 'main';
|
|
||||||
// Dataset used to render the drawer
|
|
||||||
const mainData = [
|
|
||||||
{
|
|
||||||
name: i18n.t('screens.home'),
|
|
||||||
route: "main",
|
|
||||||
icon: "home",
|
|
||||||
},
|
|
||||||
];
|
|
||||||
const amicaleData = [
|
|
||||||
{
|
|
||||||
name: i18n.t('screens.login'),
|
|
||||||
route: "login",
|
|
||||||
icon: "login",
|
|
||||||
onlyWhenLoggedOut: true,
|
|
||||||
shouldEmphasis: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: i18n.t('screens.amicaleAbout'),
|
|
||||||
route: "amicale-contact",
|
|
||||||
icon: "information",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: i18n.t('screens.profile'),
|
|
||||||
route: "profile",
|
|
||||||
icon: "account",
|
|
||||||
onlyWhenLoggedIn: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: i18n.t('clubs.clubList'),
|
|
||||||
route: "club-list",
|
|
||||||
icon: "account-group",
|
|
||||||
onlyWhenLoggedIn: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: i18n.t('screens.vote'),
|
|
||||||
route: "vote",
|
|
||||||
icon: "vote",
|
|
||||||
onlyWhenLoggedIn: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: i18n.t('screens.logout'),
|
|
||||||
route: 'disconnect',
|
|
||||||
action: this.showDisconnectDialog,
|
|
||||||
icon: "logout",
|
|
||||||
onlyWhenLoggedIn: true,
|
|
||||||
},
|
|
||||||
];
|
|
||||||
const servicesData = [
|
|
||||||
{
|
|
||||||
name: i18n.t('screens.menuSelf'),
|
|
||||||
route: "self-menu",
|
|
||||||
icon: "silverware-fork-knife",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: i18n.t('screens.availableRooms'),
|
|
||||||
route: "available-rooms",
|
|
||||||
icon: "calendar-check",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: i18n.t('screens.bib'),
|
|
||||||
route: "bib",
|
|
||||||
icon: "book",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: i18n.t('screens.bluemind'),
|
|
||||||
route: "bluemind",
|
|
||||||
link: "https://etud-mel.insa-toulouse.fr/webmail/",
|
|
||||||
icon: "email",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: i18n.t('screens.ent'),
|
|
||||||
route: "ent",
|
|
||||||
link: "https://ent.insa-toulouse.fr/",
|
|
||||||
icon: "notebook",
|
|
||||||
},
|
|
||||||
];
|
|
||||||
const websitesData = [
|
|
||||||
{
|
|
||||||
name: "Amicale",
|
|
||||||
route: "amicale-website",
|
|
||||||
icon: "alpha-a-box",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "Élus Étudiants",
|
|
||||||
route: "elus-etudiants",
|
|
||||||
icon: "alpha-e-box",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "Wiketud",
|
|
||||||
route: "wiketud",
|
|
||||||
icon: "wikipedia",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "Tutor'INSA",
|
|
||||||
route: "tutorinsa",
|
|
||||||
icon: "school",
|
|
||||||
},
|
|
||||||
];
|
|
||||||
const othersData = [
|
|
||||||
{
|
|
||||||
name: i18n.t('screens.settings'),
|
|
||||||
route: "settings",
|
|
||||||
icon: "settings",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: i18n.t('screens.about'),
|
|
||||||
route: "about",
|
|
||||||
icon: "information",
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
this.dataSet = [
|
|
||||||
{
|
|
||||||
key: '1',
|
|
||||||
name: i18n.t('screens.home'),
|
|
||||||
startOpen: true, // App always starts on Main
|
|
||||||
data: mainData
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: '2',
|
|
||||||
name: i18n.t('sidenav.divider4'),
|
|
||||||
startOpen: false, // TODO set by user preferences
|
|
||||||
data: amicaleData
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: '3',
|
|
||||||
name: i18n.t('sidenav.divider2'),
|
|
||||||
startOpen: false,
|
|
||||||
data: servicesData
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: '4',
|
|
||||||
name: i18n.t('sidenav.divider1'),
|
|
||||||
startOpen: false,
|
|
||||||
data: websitesData
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: '5',
|
|
||||||
name: i18n.t('sidenav.divider3'),
|
|
||||||
startOpen: false,
|
|
||||||
data: othersData
|
|
||||||
},
|
|
||||||
];
|
|
||||||
ConnectionManager.getInstance().addLoginStateListener(this.onLoginStateChange);
|
|
||||||
this.state = {
|
|
||||||
isLoggedIn: ConnectionManager.getInstance().isLoggedIn(),
|
|
||||||
dialogVisible: false,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
shouldComponentUpdate(nextProps: Props, nextState: State): boolean {
|
|
||||||
const nextNavigationState = nextProps.state.routes[0].state;
|
|
||||||
const nextRoute = nextNavigationState.routes[nextNavigationState.index].name;
|
|
||||||
|
|
||||||
let currentRoute = "main";
|
|
||||||
const currentNavigationState = this.props.state.routes[0].state;
|
|
||||||
if (currentNavigationState != null) {
|
|
||||||
currentRoute = currentNavigationState.routes[currentNavigationState.index].name;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
this.activeRoute = nextRoute;
|
|
||||||
return (nextState !== this.state)
|
|
||||||
|| (nextRoute !== currentRoute);
|
|
||||||
}
|
|
||||||
|
|
||||||
showDisconnectDialog = () => this.setState({dialogVisible: true});
|
|
||||||
|
|
||||||
hideDisconnectDialog = () => this.setState({dialogVisible: false});
|
|
||||||
|
|
||||||
onLoginStateChange = (isLoggedIn: boolean) => this.setState({isLoggedIn: isLoggedIn});
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the render item for the given list item
|
|
||||||
*
|
|
||||||
* @param item The item to render
|
|
||||||
* @return {*}
|
|
||||||
*/
|
|
||||||
getRenderItem = ({item}: Object) => {
|
|
||||||
return <SideBarSection
|
|
||||||
{...this.props}
|
|
||||||
listKey={item.key}
|
|
||||||
activeRoute={this.activeRoute}
|
|
||||||
isLoggedIn={this.state.isLoggedIn}
|
|
||||||
sectionName={item.name}
|
|
||||||
startOpen={item.startOpen}
|
|
||||||
listData={item.data}
|
|
||||||
/>
|
|
||||||
};
|
|
||||||
|
|
||||||
render() {
|
|
||||||
return (
|
|
||||||
<View style={{height: '100%'}}>
|
|
||||||
<TouchableRipple
|
|
||||||
onPress={() => this.props.navigation.navigate("tetris")}
|
|
||||||
>
|
|
||||||
<Image
|
|
||||||
source={require("../../../assets/drawer-cover.png")}
|
|
||||||
style={styles.drawerCover}
|
|
||||||
/>
|
|
||||||
</TouchableRipple>
|
|
||||||
{/*$FlowFixMe*/}
|
|
||||||
<FlatList
|
|
||||||
data={this.dataSet}
|
|
||||||
extraData={this.state.isLoggedIn.toString() + this.activeRoute}
|
|
||||||
renderItem={this.getRenderItem}
|
|
||||||
/>
|
|
||||||
<LogoutDialog
|
|
||||||
{...this.props}
|
|
||||||
visible={this.state.dialogVisible}
|
|
||||||
onDismiss={this.hideDisconnectDialog}
|
|
||||||
/>
|
|
||||||
</View>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const styles = StyleSheet.create({
|
|
||||||
drawerCover: {
|
|
||||||
height: deviceWidth / 3,
|
|
||||||
width: 2 * deviceWidth / 3,
|
|
||||||
position: "relative",
|
|
||||||
marginBottom: 10,
|
|
||||||
marginTop: 20
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
export default SideBar;
|
|
||||||
|
|
@ -19,8 +19,8 @@ type State = {
|
||||||
|
|
||||||
const TAB_ICONS = {
|
const TAB_ICONS = {
|
||||||
proxiwash: 'tshirt-crew',
|
proxiwash: 'tshirt-crew',
|
||||||
students: 'account-circle',
|
services: 'account-circle',
|
||||||
insa: 'book',
|
planning: 'calendar-range',
|
||||||
planex: 'clock',
|
planex: 'clock',
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,8 @@ import AboutDependenciesScreen from '../screens/About/AboutDependenciesScreen';
|
||||||
import DebugScreen from '../screens/About/DebugScreen';
|
import DebugScreen from '../screens/About/DebugScreen';
|
||||||
import {createStackNavigator, TransitionPresets} from "@react-navigation/stack";
|
import {createStackNavigator, TransitionPresets} from "@react-navigation/stack";
|
||||||
import i18n from "i18n-js";
|
import i18n from "i18n-js";
|
||||||
import TabNavigator from "./MainTabNavigator";
|
import TabNavigator from "./TabNavigator";
|
||||||
|
import TetrisScreen from "../screens/Tetris/TetrisScreen";
|
||||||
|
|
||||||
const defaultScreenOptions = {
|
const defaultScreenOptions = {
|
||||||
gestureEnabled: true,
|
gestureEnabled: true,
|
||||||
|
|
@ -59,6 +60,13 @@ function MainStackComponent(props: { createTabNavigator: () => React.Node }) {
|
||||||
title: i18n.t('aboutScreen.debug')
|
title: i18n.t('aboutScreen.debug')
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
<MainStack.Screen
|
||||||
|
name="tetris"
|
||||||
|
component={TetrisScreen}
|
||||||
|
options={{
|
||||||
|
title: i18n.t("game.title"),
|
||||||
|
}}
|
||||||
|
/>
|
||||||
</MainStack.Navigator>
|
</MainStack.Navigator>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -68,7 +76,7 @@ type Props = {
|
||||||
defaultHomeData: { [key: string]: any }
|
defaultHomeData: { [key: string]: any }
|
||||||
}
|
}
|
||||||
|
|
||||||
export default class DrawerNavigator extends React.Component<Props> {
|
export default class MainNavigator extends React.Component<Props> {
|
||||||
|
|
||||||
createTabNavigator: () => React.Node;
|
createTabNavigator: () => React.Node;
|
||||||
|
|
||||||
|
|
@ -21,23 +21,23 @@ import FeedItemScreen from "../screens/Home/FeedItemScreen";
|
||||||
import {createCollapsibleStack} from "react-navigation-collapsible";
|
import {createCollapsibleStack} from "react-navigation-collapsible";
|
||||||
import GroupSelectionScreen from "../screens/Planex/GroupSelectionScreen";
|
import GroupSelectionScreen from "../screens/Planex/GroupSelectionScreen";
|
||||||
import CustomTabBar from "../components/Tabbar/CustomTabBar";
|
import CustomTabBar from "../components/Tabbar/CustomTabBar";
|
||||||
import SelfMenuScreen from "../screens/Other/SelfMenuScreen";
|
import SelfMenuScreen from "../screens/Services/SelfMenuScreen";
|
||||||
import AvailableRoomScreen from "../screens/Websites/AvailableRoomScreen";
|
import AvailableRoomScreen from "../screens/Websites/AvailableRoomScreen";
|
||||||
import BibScreen from "../screens/Websites/BibScreen";
|
import BibScreen from "../screens/Websites/BibScreen";
|
||||||
import {AmicaleWebsiteScreen} from "../screens/Websites/AmicaleWebsiteScreen";
|
import {AmicaleWebsiteScreen} from "../screens/Websites/AmicaleWebsiteScreen";
|
||||||
import {ElusEtudiantsWebsiteScreen} from "../screens/Websites/ElusEtudiantsWebsiteScreen";
|
import {ElusEtudiantsWebsiteScreen} from "../screens/Websites/ElusEtudiantsWebsiteScreen";
|
||||||
import {WiketudWebsiteScreen} from "../screens/Websites/WiketudWebsiteScreen";
|
import {WiketudWebsiteScreen} from "../screens/Websites/WiketudWebsiteScreen";
|
||||||
import {TutorInsaWebsiteScreen} from "../screens/Websites/TutorInsaWebsiteScreen";
|
import {TutorInsaWebsiteScreen} from "../screens/Websites/TutorInsaWebsiteScreen";
|
||||||
import TetrisScreen from "../screens/Tetris/TetrisScreen";
|
import {ENTWebsiteScreen} from "../screens/Websites/ENTWebsiteScreen";
|
||||||
|
import {BlueMindWebsiteScreen} from "../screens/Websites/BlueMindWebsiteScreen";
|
||||||
import LoginScreen from "../screens/Amicale/LoginScreen";
|
import LoginScreen from "../screens/Amicale/LoginScreen";
|
||||||
import ProfileScreen from "../screens/Amicale/ProfileScreen";
|
import ProfileScreen from "../screens/Amicale/ProfileScreen";
|
||||||
import ClubListScreen from "../screens/Amicale/Clubs/ClubListScreen";
|
import ClubListScreen from "../screens/Amicale/Clubs/ClubListScreen";
|
||||||
import ClubAboutScreen from "../screens/Amicale/Clubs/ClubAboutScreen";
|
import ClubAboutScreen from "../screens/Amicale/Clubs/ClubAboutScreen";
|
||||||
import VoteScreen from "../screens/Amicale/VoteScreen";
|
import VoteScreen from "../screens/Amicale/VoteScreen";
|
||||||
import AmicaleContactScreen from "../screens/Amicale/AmicaleContactScreen";
|
import AmicaleContactScreen from "../screens/Amicale/AmicaleContactScreen";
|
||||||
import AmicaleHomeScreen from "../screens/Amicale/AmicaleHomeScreen";
|
import WebsitesHomeScreen from "../screens/Services/ServicesScreen";
|
||||||
import WebsitesHomeScreen from "../screens/Websites/WebsitesHomeScreen";
|
import ServicesSectionScreen from "../screens/Services/ServicesSectionScreen";
|
||||||
import InsaHomeScreen from "../screens/Insa/InsaHomeScreen";
|
|
||||||
|
|
||||||
const defaultScreenOptions = {
|
const defaultScreenOptions = {
|
||||||
gestureEnabled: true,
|
gestureEnabled: true,
|
||||||
|
|
@ -82,36 +82,34 @@ function getWebsiteStack(name: string, Stack: any, component: any, title: strin
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const StudentsStack = createStackNavigator();
|
const ServicesStack = createStackNavigator();
|
||||||
|
|
||||||
function StudentsStackComponent() {
|
function ServicesStackComponent() {
|
||||||
return (
|
return (
|
||||||
<StudentsStack.Navigator
|
<ServicesStack.Navigator
|
||||||
initialRouteName="index"
|
initialRouteName="index"
|
||||||
headerMode={"screen"}
|
headerMode={"screen"}
|
||||||
screenOptions={defaultScreenOptions}
|
screenOptions={defaultScreenOptions}
|
||||||
>
|
>
|
||||||
<StudentsStack.Screen
|
{createScreenCollapsibleStack("index", ServicesStack, WebsitesHomeScreen, i18n.t('screens.services'))}
|
||||||
name="index"
|
{createScreenCollapsibleStack("services-section", ServicesStack, ServicesSectionScreen, "SECTION")}
|
||||||
component={WebsitesHomeScreen}
|
|
||||||
options={{
|
{/* INSA */}
|
||||||
title: "WEBSITES HOME",
|
{getWebsiteStack("available-rooms", ServicesStack, AvailableRoomScreen, i18n.t('screens.availableRooms'))}
|
||||||
}}
|
{getWebsiteStack("bib", ServicesStack, BibScreen, i18n.t('screens.bib'))}
|
||||||
/>
|
{createScreenCollapsibleStack("self-menu", ServicesStack, SelfMenuScreen, i18n.t('screens.menuSelf'))}
|
||||||
{getWebsiteStack("amicale-website", StudentsStack, AmicaleWebsiteScreen, "Amicale")}
|
|
||||||
{getWebsiteStack("elus-etudiants", StudentsStack, ElusEtudiantsWebsiteScreen, "Élus Étudiants")}
|
{/* STUDENTS */}
|
||||||
{getWebsiteStack("wiketud", StudentsStack, WiketudWebsiteScreen, "Wiketud")}
|
{createScreenCollapsibleStack("proximo", ServicesStack, ProximoMainScreen, i18n.t('screens.proximo'))}
|
||||||
{getWebsiteStack("tutorinsa", StudentsStack, TutorInsaWebsiteScreen, "Tutor'INSA")}
|
|
||||||
{createScreenCollapsibleStack("proximo", StudentsStack, ProximoMainScreen, "Proximo")}
|
|
||||||
{createScreenCollapsibleStack(
|
{createScreenCollapsibleStack(
|
||||||
"proximo-list",
|
"proximo-list",
|
||||||
StudentsStack,
|
ServicesStack,
|
||||||
ProximoListScreen,
|
ProximoListScreen,
|
||||||
i18n.t('screens.proximoArticles'),
|
i18n.t('screens.proximoArticles'),
|
||||||
true,
|
true,
|
||||||
{...screenTransition},
|
{...screenTransition},
|
||||||
)}
|
)}
|
||||||
<StudentsStack.Screen
|
<ServicesStack.Screen
|
||||||
name="proximo-about"
|
name="proximo-about"
|
||||||
component={ProximoAboutScreen}
|
component={ProximoAboutScreen}
|
||||||
options={{
|
options={{
|
||||||
|
|
@ -119,22 +117,41 @@ function StudentsStackComponent() {
|
||||||
...modalTransition,
|
...modalTransition,
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<StudentsStack.Screen
|
{getWebsiteStack("amicale-website", ServicesStack, AmicaleWebsiteScreen, i18n.t('screens.amicaleWebsite'))}
|
||||||
name="planning"
|
{getWebsiteStack("elus-etudiants", ServicesStack, ElusEtudiantsWebsiteScreen, "Élus Étudiants")}
|
||||||
component={PlanningScreen}
|
{getWebsiteStack("wiketud", ServicesStack, WiketudWebsiteScreen, "Wiketud")}
|
||||||
|
{getWebsiteStack("tutorinsa", ServicesStack, TutorInsaWebsiteScreen, "Tutor'INSA")}
|
||||||
|
{getWebsiteStack("ent", ServicesStack, ENTWebsiteScreen, i18n.t('screens.ent'))}
|
||||||
|
{getWebsiteStack("bluemind", ServicesStack, BlueMindWebsiteScreen, i18n.t('screens.bluemind'))}
|
||||||
|
|
||||||
|
|
||||||
|
{/* AMICALE */}
|
||||||
|
{createScreenCollapsibleStack("login", ServicesStack, LoginScreen, i18n.t('screens.login'))}
|
||||||
|
{createScreenCollapsibleStack("profile", ServicesStack, ProfileScreen, i18n.t('screens.profile'))}
|
||||||
|
{createScreenCollapsibleStack("club-list", ServicesStack, ClubListScreen, i18n.t('clubs.clubList'))}
|
||||||
|
<ServicesStack.Screen
|
||||||
|
name="club-about"
|
||||||
|
component={ClubAboutScreen}
|
||||||
options={{
|
options={{
|
||||||
title: i18n.t('screens.planning'),
|
title: i18n.t('screens.clubsAbout'),
|
||||||
}}
|
|
||||||
/>
|
|
||||||
<StudentsStack.Screen
|
|
||||||
name="planning-information"
|
|
||||||
component={PlanningDisplayScreen}
|
|
||||||
options={{
|
|
||||||
title: i18n.t('screens.planningDisplayScreen'),
|
|
||||||
...modalTransition,
|
...modalTransition,
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</StudentsStack.Navigator>
|
<ServicesStack.Screen
|
||||||
|
name="vote"
|
||||||
|
component={VoteScreen}
|
||||||
|
options={{
|
||||||
|
title: i18n.t('screens.vote'),
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<ServicesStack.Screen
|
||||||
|
name="amicale-contact"
|
||||||
|
component={AmicaleContactScreen}
|
||||||
|
options={{
|
||||||
|
title: i18n.t('screens.amicaleAbout'),
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</ServicesStack.Navigator>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -160,26 +177,31 @@ function ProxiwashStackComponent() {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const InsaStack = createStackNavigator();
|
const PlanningStack = createStackNavigator();
|
||||||
|
|
||||||
function InsaStackComponent() {
|
function PlanningStackComponent() {
|
||||||
return (
|
return (
|
||||||
<InsaStack.Navigator
|
<PlanningStack.Navigator
|
||||||
initialRouteName="index"
|
initialRouteName="index"
|
||||||
headerMode={"screen"}
|
headerMode={"screen"}
|
||||||
screenOptions={defaultScreenOptions}
|
screenOptions={defaultScreenOptions}
|
||||||
>
|
>
|
||||||
<InsaStack.Screen
|
<PlanningStack.Screen
|
||||||
name="index"
|
name="planning"
|
||||||
component={InsaHomeScreen}
|
component={PlanningScreen}
|
||||||
options={{
|
options={{
|
||||||
title: "INSA HOME",
|
title: i18n.t('screens.planning'),
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
{getWebsiteStack("available-rooms", InsaStack, AvailableRoomScreen, i18n.t('screens.availableRooms'))}
|
<PlanningStack.Screen
|
||||||
{getWebsiteStack("bib", InsaStack, BibScreen, i18n.t('screens.bib'))}
|
name="planning-information"
|
||||||
{createScreenCollapsibleStack("self-menu", InsaStack, SelfMenuScreen, i18n.t('screens.menuSelf'))}
|
component={PlanningDisplayScreen}
|
||||||
</InsaStack.Navigator>
|
options={{
|
||||||
|
title: i18n.t('screens.planningDisplayScreen'),
|
||||||
|
...modalTransition,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</PlanningStack.Navigator>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -213,14 +235,6 @@ function HomeStackComponent(initialRoute: string | null, defaultData: { [key: st
|
||||||
useNativeDriver: true,
|
useNativeDriver: true,
|
||||||
}
|
}
|
||||||
)}
|
)}
|
||||||
<HomeStack.Screen
|
|
||||||
name="feed-information"
|
|
||||||
component={FeedItemScreen}
|
|
||||||
options={{
|
|
||||||
title: i18n.t('screens.feedDisplayScreen'),
|
|
||||||
...modalTransition,
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
<HomeStack.Screen
|
<HomeStack.Screen
|
||||||
name="scanner"
|
name="scanner"
|
||||||
component={ScannerScreen}
|
component={ScannerScreen}
|
||||||
|
|
@ -229,36 +243,6 @@ function HomeStackComponent(initialRoute: string | null, defaultData: { [key: st
|
||||||
...modalTransition,
|
...modalTransition,
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<HomeStack.Screen
|
|
||||||
name="home-planning-information"
|
|
||||||
component={PlanningDisplayScreen}
|
|
||||||
options={{
|
|
||||||
title: i18n.t('screens.planningDisplayScreen'),
|
|
||||||
...modalTransition,
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
<HomeStack.Screen
|
|
||||||
name="tetris"
|
|
||||||
component={TetrisScreen}
|
|
||||||
options={{
|
|
||||||
title: i18n.t("game.title"),
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
<HomeStack.Screen
|
|
||||||
name="login"
|
|
||||||
component={LoginScreen}
|
|
||||||
options={{
|
|
||||||
title: i18n.t('screens.login'),
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
<HomeStack.Screen
|
|
||||||
name="profile"
|
|
||||||
component={ProfileScreen}
|
|
||||||
options={{
|
|
||||||
title: i18n.t('screens.profile'),
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
{createScreenCollapsibleStack("club-list", HomeStack, ClubListScreen, i18n.t('clubs.clubList'))}
|
|
||||||
<HomeStack.Screen
|
<HomeStack.Screen
|
||||||
name="club-information"
|
name="club-information"
|
||||||
component={ClubDisplayScreen}
|
component={ClubDisplayScreen}
|
||||||
|
|
@ -268,34 +252,23 @@ function HomeStackComponent(initialRoute: string | null, defaultData: { [key: st
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<HomeStack.Screen
|
<HomeStack.Screen
|
||||||
name="club-about"
|
name="feed-information"
|
||||||
component={ClubAboutScreen}
|
component={FeedItemScreen}
|
||||||
options={{
|
options={{
|
||||||
title: i18n.t('screens.clubsAbout'),
|
title: i18n.t('screens.feedDisplayScreen'),
|
||||||
...modalTransition,
|
...modalTransition,
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<HomeStack.Screen
|
<HomeStack.Screen
|
||||||
name="vote"
|
name="planning-information"
|
||||||
component={VoteScreen}
|
component={PlanningDisplayScreen}
|
||||||
options={{
|
options={{
|
||||||
title: i18n.t('screens.vote'),
|
title: i18n.t('screens.planningDisplayScreen'),
|
||||||
}}
|
...modalTransition,
|
||||||
/>
|
|
||||||
<HomeStack.Screen
|
|
||||||
name="amicale-contact"
|
|
||||||
component={AmicaleContactScreen}
|
|
||||||
options={{
|
|
||||||
title: i18n.t('screens.amicaleAbout'),
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
<HomeStack.Screen
|
|
||||||
name="amicale-home"
|
|
||||||
component={AmicaleHomeScreen}
|
|
||||||
options={{
|
|
||||||
title: "AMICALE HOME",
|
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
{createScreenCollapsibleStack("self-menu", HomeStack, SelfMenuScreen, i18n.t('screens.menuSelf'), true, {...modalTransition})}
|
||||||
|
{createScreenCollapsibleStack("login", HomeStack, LoginScreen, i18n.t('screens.login'))}
|
||||||
</HomeStack.Navigator>
|
</HomeStack.Navigator>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -348,27 +321,26 @@ export default class TabNavigator extends React.Component<Props> {
|
||||||
initialRouteName={this.defaultRoute}
|
initialRouteName={this.defaultRoute}
|
||||||
tabBar={props => <CustomTabBar {...props} />}
|
tabBar={props => <CustomTabBar {...props} />}
|
||||||
>
|
>
|
||||||
|
<Tab.Screen
|
||||||
|
name="services"
|
||||||
|
option
|
||||||
|
component={ServicesStackComponent}
|
||||||
|
options={{title: i18n.t('screens.services')}}
|
||||||
|
/>
|
||||||
<Tab.Screen
|
<Tab.Screen
|
||||||
name="proxiwash"
|
name="proxiwash"
|
||||||
component={ProxiwashStackComponent}
|
component={ProxiwashStackComponent}
|
||||||
options={{title: i18n.t('screens.proxiwash')}}
|
options={{title: i18n.t('screens.proxiwash')}}
|
||||||
/>
|
/>
|
||||||
<Tab.Screen
|
|
||||||
name="students"
|
|
||||||
option
|
|
||||||
component={StudentsStackComponent}
|
|
||||||
options={{title: "ETUDIANTS"}}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<Tab.Screen
|
<Tab.Screen
|
||||||
name="home"
|
name="home"
|
||||||
component={this.createHomeStackComponent}
|
component={this.createHomeStackComponent}
|
||||||
options={{title: i18n.t('screens.home')}}
|
options={{title: i18n.t('screens.home')}}
|
||||||
/>
|
/>
|
||||||
<Tab.Screen
|
<Tab.Screen
|
||||||
name="insa"
|
name="planning"
|
||||||
component={InsaStackComponent}
|
component={PlanningStackComponent}
|
||||||
options={{title: "INSA"}}
|
options={{title: i18n.t('screens.planning')}}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Tab.Screen
|
<Tab.Screen
|
||||||
|
|
@ -1,16 +1,21 @@
|
||||||
// @flow
|
// @flow
|
||||||
|
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import {KeyboardAvoidingView, ScrollView, StyleSheet, View} from "react-native";
|
import {Animated, KeyboardAvoidingView, StyleSheet, View} from "react-native";
|
||||||
import {Avatar, Button, Card, HelperText, Paragraph, TextInput, withTheme} from 'react-native-paper';
|
import {Avatar, Button, Card, HelperText, Paragraph, TextInput, withTheme} from 'react-native-paper';
|
||||||
import ConnectionManager from "../../managers/ConnectionManager";
|
import ConnectionManager from "../../managers/ConnectionManager";
|
||||||
import i18n from 'i18n-js';
|
import i18n from 'i18n-js';
|
||||||
import ErrorDialog from "../../components/Dialogs/ErrorDialog";
|
import ErrorDialog from "../../components/Dialogs/ErrorDialog";
|
||||||
import {CommonActions} from "@react-navigation/native";
|
import {withCollapsible} from "../../utils/withCollapsible";
|
||||||
|
import {Collapsible} from "react-navigation-collapsible";
|
||||||
|
import CustomTabBar from "../../components/Tabbar/CustomTabBar";
|
||||||
|
import type {CustomTheme} from "../../managers/ThemeManager";
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
navigation: Object,
|
navigation: Object,
|
||||||
route: Object,
|
route: Object,
|
||||||
|
collapsibleStack: Collapsible,
|
||||||
|
theme: CustomTheme
|
||||||
}
|
}
|
||||||
|
|
||||||
type State = {
|
type State = {
|
||||||
|
|
@ -41,32 +46,17 @@ class LoginScreen extends React.Component<Props, State> {
|
||||||
dialogError: 0,
|
dialogError: 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
colors: Object;
|
|
||||||
|
|
||||||
onEmailChange: Function;
|
onEmailChange: Function;
|
||||||
onPasswordChange: Function;
|
onPasswordChange: Function;
|
||||||
passwordInputRef: Object;
|
passwordInputRef: Object;
|
||||||
|
|
||||||
nextScreen: string;
|
|
||||||
|
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
this.onEmailChange = this.onInputChange.bind(this, true);
|
this.onEmailChange = this.onInputChange.bind(this, true);
|
||||||
this.onPasswordChange = this.onInputChange.bind(this, false);
|
this.onPasswordChange = this.onInputChange.bind(this, false);
|
||||||
|
|
||||||
this.colors = props.theme.colors;
|
|
||||||
|
|
||||||
this.props.navigation.addListener('focus', this.onScreenFocus);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
onScreenFocus = () => {
|
|
||||||
if (this.props.route.params !== undefined && this.props.route.params.nextScreen !== undefined) {
|
|
||||||
this.nextScreen = this.props.route.params.nextScreen;
|
|
||||||
this.props.navigation.dispatch(CommonActions.setParams({nextScreen: 'profile'}));
|
|
||||||
} else
|
|
||||||
this.nextScreen = 'profile';
|
|
||||||
};
|
|
||||||
|
|
||||||
showErrorDialog = (error: number) =>
|
showErrorDialog = (error: number) =>
|
||||||
this.setState({
|
this.setState({
|
||||||
dialogVisible: true,
|
dialogVisible: true,
|
||||||
|
|
@ -75,7 +65,7 @@ class LoginScreen extends React.Component<Props, State> {
|
||||||
|
|
||||||
hideErrorDialog = () => this.setState({dialogVisible: false});
|
hideErrorDialog = () => this.setState({dialogVisible: false});
|
||||||
|
|
||||||
handleSuccess = () => this.props.navigation.replace(this.nextScreen);
|
handleSuccess = () => this.props.navigation.goBack();
|
||||||
|
|
||||||
onResetPasswordClick = () => this.props.navigation.navigate('amicale-website', {
|
onResetPasswordClick = () => this.props.navigation.navigate('amicale-website', {
|
||||||
screen: 'amicale-website',
|
screen: 'amicale-website',
|
||||||
|
|
@ -235,7 +225,7 @@ class LoginScreen extends React.Component<Props, State> {
|
||||||
left={(props) => <Avatar.Icon
|
left={(props) => <Avatar.Icon
|
||||||
{...props}
|
{...props}
|
||||||
icon={"help"}
|
icon={"help"}
|
||||||
color={this.colors.primary}
|
color={this.props.theme.colors.primary}
|
||||||
style={{backgroundColor: 'transparent'}}/>}
|
style={{backgroundColor: 'transparent'}}/>}
|
||||||
/>
|
/>
|
||||||
<Card.Content>
|
<Card.Content>
|
||||||
|
|
@ -248,6 +238,7 @@ class LoginScreen extends React.Component<Props, State> {
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
const {containerPaddingTop, scrollIndicatorInsetTop, onScroll} = this.props.collapsibleStack;
|
||||||
return (
|
return (
|
||||||
<KeyboardAvoidingView
|
<KeyboardAvoidingView
|
||||||
behavior={"height"}
|
behavior={"height"}
|
||||||
|
|
@ -256,7 +247,14 @@ class LoginScreen extends React.Component<Props, State> {
|
||||||
enabled
|
enabled
|
||||||
keyboardVerticalOffset={100}
|
keyboardVerticalOffset={100}
|
||||||
>
|
>
|
||||||
<ScrollView>
|
<Animated.ScrollView
|
||||||
|
onScroll={onScroll}
|
||||||
|
contentContainerStyle={{
|
||||||
|
paddingTop: containerPaddingTop,
|
||||||
|
paddingBottom: CustomTabBar.TAB_BAR_HEIGHT + 20
|
||||||
|
}}
|
||||||
|
scrollIndicatorInsets={{top: scrollIndicatorInsetTop}}
|
||||||
|
>
|
||||||
<View>
|
<View>
|
||||||
{this.getMainCard()}
|
{this.getMainCard()}
|
||||||
{this.getSecondaryCard()}
|
{this.getSecondaryCard()}
|
||||||
|
|
@ -266,7 +264,7 @@ class LoginScreen extends React.Component<Props, State> {
|
||||||
onDismiss={this.hideErrorDialog}
|
onDismiss={this.hideErrorDialog}
|
||||||
errorCode={this.state.dialogError}
|
errorCode={this.state.dialogError}
|
||||||
/>
|
/>
|
||||||
</ScrollView>
|
</Animated.ScrollView>
|
||||||
</KeyboardAvoidingView>
|
</KeyboardAvoidingView>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -292,4 +290,4 @@ const styles = StyleSheet.create({
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
export default withTheme(LoginScreen);
|
export default withCollapsible(withTheme(LoginScreen));
|
||||||
|
|
|
||||||
|
|
@ -1,16 +1,20 @@
|
||||||
// @flow
|
// @flow
|
||||||
|
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import {FlatList, StyleSheet, View} from "react-native";
|
import {Animated, FlatList, StyleSheet, View} from "react-native";
|
||||||
import {Avatar, Button, Card, Divider, List, withTheme} from 'react-native-paper';
|
import {Avatar, Button, Card, Divider, List, withTheme} from 'react-native-paper';
|
||||||
import AuthenticatedScreen from "../../components/Amicale/AuthenticatedScreen";
|
import AuthenticatedScreen from "../../components/Amicale/AuthenticatedScreen";
|
||||||
import i18n from 'i18n-js';
|
import i18n from 'i18n-js';
|
||||||
import LogoutDialog from "../../components/Amicale/LogoutDialog";
|
import LogoutDialog from "../../components/Amicale/LogoutDialog";
|
||||||
import MaterialHeaderButtons, {Item} from "../../components/Overrides/CustomHeaderButton";
|
import MaterialHeaderButtons, {Item} from "../../components/Overrides/CustomHeaderButton";
|
||||||
|
import CustomTabBar from "../../components/Tabbar/CustomTabBar";
|
||||||
|
import {Collapsible} from "react-navigation-collapsible";
|
||||||
|
import {withCollapsible} from "../../utils/withCollapsible";
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
navigation: Object,
|
navigation: Object,
|
||||||
theme: Object,
|
theme: Object,
|
||||||
|
collapsibleStack: Collapsible,
|
||||||
}
|
}
|
||||||
|
|
||||||
type State = {
|
type State = {
|
||||||
|
|
@ -52,12 +56,20 @@ class ProfileScreen extends React.Component<Props, State> {
|
||||||
|
|
||||||
getScreen = (data: Object) => {
|
getScreen = (data: Object) => {
|
||||||
this.data = data[0];
|
this.data = data[0];
|
||||||
|
const {containerPaddingTop, scrollIndicatorInsetTop, onScroll} = this.props.collapsibleStack;
|
||||||
return (
|
return (
|
||||||
<View>
|
<View style={{flex: 1}}>
|
||||||
{/*$FlowFixMe*/}
|
<Animated.FlatList
|
||||||
<FlatList
|
|
||||||
renderItem={this.getRenderItem}
|
renderItem={this.getRenderItem}
|
||||||
data={this.flatListData}
|
data={this.flatListData}
|
||||||
|
// Animations
|
||||||
|
onScroll={onScroll}
|
||||||
|
contentContainerStyle={{
|
||||||
|
paddingTop: containerPaddingTop,
|
||||||
|
paddingBottom: CustomTabBar.TAB_BAR_HEIGHT,
|
||||||
|
minHeight: '100%'
|
||||||
|
}}
|
||||||
|
scrollIndicatorInsets={{top: scrollIndicatorInsetTop}}
|
||||||
/>
|
/>
|
||||||
<LogoutDialog
|
<LogoutDialog
|
||||||
{...this.props}
|
{...this.props}
|
||||||
|
|
@ -323,4 +335,4 @@ const styles = StyleSheet.create({
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
export default withTheme(ProfileScreen);
|
export default withCollapsible(withTheme(ProfileScreen));
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,9 @@ import AnimatedFAB from "../../components/Animations/AnimatedFAB";
|
||||||
import {StackNavigationProp} from "@react-navigation/stack";
|
import {StackNavigationProp} from "@react-navigation/stack";
|
||||||
import type {CustomTheme} from "../../managers/ThemeManager";
|
import type {CustomTheme} from "../../managers/ThemeManager";
|
||||||
import {View} from "react-native-animatable";
|
import {View} from "react-native-animatable";
|
||||||
|
import {HiddenItem} from "react-navigation-header-buttons";
|
||||||
|
import ConnectionManager from "../../managers/ConnectionManager";
|
||||||
|
import LogoutDialog from "../../components/Amicale/LogoutDialog";
|
||||||
// import DATA from "../dashboard_data.json";
|
// import DATA from "../dashboard_data.json";
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -95,21 +98,32 @@ type Props = {
|
||||||
theme: CustomTheme,
|
theme: CustomTheme,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type State = {
|
||||||
|
dialogVisible: boolean,
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class defining the app's home screen
|
* Class defining the app's home screen
|
||||||
*/
|
*/
|
||||||
class HomeScreen extends React.Component<Props> {
|
class HomeScreen extends React.Component<Props, State> {
|
||||||
|
|
||||||
colors: Object;
|
colors: Object;
|
||||||
|
|
||||||
|
isLoggedIn: boolean | null;
|
||||||
|
|
||||||
fabRef: { current: null | AnimatedFAB };
|
fabRef: { current: null | AnimatedFAB };
|
||||||
currentNewFeed: Array<feedItem>;
|
currentNewFeed: Array<feedItem>;
|
||||||
|
|
||||||
|
state = {
|
||||||
|
dialogVisible: false,
|
||||||
|
}
|
||||||
|
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
this.colors = props.theme.colors;
|
this.colors = props.theme.colors;
|
||||||
this.fabRef = React.createRef();
|
this.fabRef = React.createRef();
|
||||||
this.currentNewFeed = [];
|
this.currentNewFeed = [];
|
||||||
|
this.isLoggedIn = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -130,9 +144,12 @@ class HomeScreen extends React.Component<Props> {
|
||||||
}
|
}
|
||||||
|
|
||||||
onScreenFocus = () => {
|
onScreenFocus = () => {
|
||||||
|
if (ConnectionManager.getInstance().isLoggedIn() !== this.isLoggedIn) {
|
||||||
|
this.isLoggedIn = ConnectionManager.getInstance().isLoggedIn();
|
||||||
this.props.navigation.setOptions({
|
this.props.navigation.setOptions({
|
||||||
headerRight: this.getHeaderButton,
|
headerRight: this.getHeaderButton,
|
||||||
});
|
});
|
||||||
|
}
|
||||||
// handle link open when home is not focused or created
|
// handle link open when home is not focused or created
|
||||||
this.handleNavigationParams();
|
this.handleNavigationParams();
|
||||||
};
|
};
|
||||||
|
|
@ -148,25 +165,43 @@ class HomeScreen extends React.Component<Props> {
|
||||||
};
|
};
|
||||||
|
|
||||||
getHeaderButton = () => {
|
getHeaderButton = () => {
|
||||||
|
let onPressLog = () => this.props.navigation.navigate("login");
|
||||||
|
let logIcon = "login";
|
||||||
|
let logColor = this.props.theme.colors.primary;
|
||||||
|
if (this.isLoggedIn) {
|
||||||
|
onPressLog = () => this.showDisconnectDialog();
|
||||||
|
logIcon = "logout";
|
||||||
|
logColor = this.props.theme.colors.text;
|
||||||
|
}
|
||||||
|
|
||||||
const onPressSettings = () => this.props.navigation.navigate("settings");
|
const onPressSettings = () => this.props.navigation.navigate("settings");
|
||||||
const onPressAbout = () => this.props.navigation.navigate("about");
|
const onPressAbout = () => this.props.navigation.navigate("about");
|
||||||
return <MaterialHeaderButtons>
|
return <MaterialHeaderButtons>
|
||||||
<Item title="settings" iconName={"settings"} onPress={onPressSettings}/>
|
<Item title="log" iconName={logIcon} color={logColor} onPress={onPressLog}/>
|
||||||
<Item title="information" iconName={"information"} onPress={onPressAbout}/>
|
<HiddenItem title={i18n.t("screens.settings")} iconName={"settings"} onPress={onPressSettings}/>
|
||||||
|
<HiddenItem title={i18n.t("screens.about")} iconName={"information"} onPress={onPressAbout}/>
|
||||||
</MaterialHeaderButtons>;
|
</MaterialHeaderButtons>;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
showDisconnectDialog = () => this.setState({dialogVisible: true});
|
||||||
|
|
||||||
|
hideDisconnectDialog = () => this.setState({dialogVisible: false});
|
||||||
|
|
||||||
onProxiwashClick = () => {
|
onProxiwashClick = () => {
|
||||||
this.props.navigation.navigate("proxiwash");
|
this.props.navigation.navigate("proxiwash");
|
||||||
};
|
};
|
||||||
|
|
||||||
onProximoClick = () => {
|
onProximoClick = () => {
|
||||||
this.props.navigation.navigate("proximo");
|
this.props.navigation.navigate('services', {screen: "index"});
|
||||||
};
|
};
|
||||||
|
|
||||||
onTutorInsaClick = () => this.props.navigation.navigate('tutorinsa');
|
onTutorInsaClick = () => {
|
||||||
|
this.props.navigation.navigate('services', {screen: "index"});
|
||||||
|
};
|
||||||
|
|
||||||
onMenuClick = () => this.props.navigation.navigate('self-menu');
|
onMenuClick = () => {
|
||||||
|
this.props.navigation.navigate('self-menu');
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates the dataset to be used in the FlatList
|
* Creates the dataset to be used in the FlatList
|
||||||
|
|
@ -244,7 +279,7 @@ class HomeScreen extends React.Component<Props> {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'today_menu',
|
id: 'today_menu',
|
||||||
data: dashboardData == null ? 0 : dashboardData.today_menu,
|
data: dashboardData == null ? [] : dashboardData.today_menu,
|
||||||
icon: 'silverware-fork-knife',
|
icon: 'silverware-fork-knife',
|
||||||
color: this.colors.menuColor,
|
color: this.colors.menuColor,
|
||||||
onPress: this.onMenuClick,
|
onPress: this.onMenuClick,
|
||||||
|
|
@ -277,7 +312,7 @@ class HomeScreen extends React.Component<Props> {
|
||||||
}
|
}
|
||||||
|
|
||||||
getDashboardActions() {
|
getDashboardActions() {
|
||||||
return <ActionsDashBoardItem {...this.props}/>;
|
return <ActionsDashBoardItem {...this.props} isLoggedIn={this.isLoggedIn}/>;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -407,8 +442,11 @@ class HomeScreen extends React.Component<Props> {
|
||||||
getDashboardEvent(content: Array<event>) {
|
getDashboardEvent(content: Array<event>) {
|
||||||
let futureEvents = this.getFutureEvents(content);
|
let futureEvents = this.getFutureEvents(content);
|
||||||
let displayEvent = this.getDisplayEvent(futureEvents);
|
let displayEvent = this.getDisplayEvent(futureEvents);
|
||||||
const clickPreviewAction = () =>
|
// const clickPreviewAction = () =>
|
||||||
this.props.navigation.navigate('home-planning-information', {data: displayEvent});
|
// this.props.navigation.navigate('students', {
|
||||||
|
// screen: 'planning-information',
|
||||||
|
// params: {data: displayEvent}
|
||||||
|
// });
|
||||||
return (
|
return (
|
||||||
<DashboardItem
|
<DashboardItem
|
||||||
eventNumber={futureEvents.length}
|
eventNumber={futureEvents.length}
|
||||||
|
|
@ -416,7 +454,7 @@ class HomeScreen extends React.Component<Props> {
|
||||||
>
|
>
|
||||||
<PreviewEventDashboardItem
|
<PreviewEventDashboardItem
|
||||||
event={displayEvent != null ? displayEvent : undefined}
|
event={displayEvent != null ? displayEvent : undefined}
|
||||||
clickAction={clickPreviewAction}
|
clickAction={this.onEventContainerClick}
|
||||||
/>
|
/>
|
||||||
</DashboardItem>
|
</DashboardItem>
|
||||||
);
|
);
|
||||||
|
|
@ -522,6 +560,11 @@ class HomeScreen extends React.Component<Props> {
|
||||||
icon="qrcode-scan"
|
icon="qrcode-scan"
|
||||||
onPress={this.openScanner}
|
onPress={this.openScanner}
|
||||||
/>
|
/>
|
||||||
|
<LogoutDialog
|
||||||
|
{...this.props}
|
||||||
|
visible={this.state.dialogVisible}
|
||||||
|
onDismiss={this.hideDisconnectDialog}
|
||||||
|
/>
|
||||||
</View>
|
</View>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,85 +0,0 @@
|
||||||
// @flow
|
|
||||||
|
|
||||||
import * as React from 'react';
|
|
||||||
import {ScrollView, StyleSheet} from "react-native";
|
|
||||||
import {Button, withTheme} from 'react-native-paper';
|
|
||||||
|
|
||||||
type Props = {
|
|
||||||
navigation: Object,
|
|
||||||
route: Object,
|
|
||||||
}
|
|
||||||
|
|
||||||
type State = {}
|
|
||||||
|
|
||||||
class InsaHomeScreen extends React.Component<Props, State> {
|
|
||||||
|
|
||||||
state = {};
|
|
||||||
|
|
||||||
colors: Object;
|
|
||||||
|
|
||||||
constructor(props) {
|
|
||||||
super(props);
|
|
||||||
|
|
||||||
this.colors = props.theme.colors;
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
|
||||||
const nav = this.props.navigation;
|
|
||||||
return (
|
|
||||||
<ScrollView>
|
|
||||||
<Button
|
|
||||||
icon={"information"}
|
|
||||||
onPress={() => nav.navigate("self-menu")}
|
|
||||||
>
|
|
||||||
RU
|
|
||||||
</Button>
|
|
||||||
<Button
|
|
||||||
icon={"information"}
|
|
||||||
onPress={() => nav.navigate("available-rooms")}
|
|
||||||
>
|
|
||||||
AVAILABLE ROOMS
|
|
||||||
</Button>
|
|
||||||
<Button
|
|
||||||
icon={"information"}
|
|
||||||
onPress={() => nav.navigate("bib")}
|
|
||||||
>
|
|
||||||
BIB
|
|
||||||
</Button>
|
|
||||||
<Button// TODO create webview
|
|
||||||
icon={"information"}
|
|
||||||
onPress={() => nav.navigate("self-menu")}
|
|
||||||
>
|
|
||||||
EMAIL
|
|
||||||
</Button>
|
|
||||||
<Button// TODO create webview
|
|
||||||
icon={"information"}
|
|
||||||
onPress={() => nav.navigate("self-menu")}
|
|
||||||
>
|
|
||||||
ENT
|
|
||||||
</Button>
|
|
||||||
</ScrollView>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const styles = StyleSheet.create({
|
|
||||||
container: {
|
|
||||||
flex: 1,
|
|
||||||
flexDirection: 'column',
|
|
||||||
justifyContent: 'center',
|
|
||||||
},
|
|
||||||
card: {
|
|
||||||
margin: 10,
|
|
||||||
},
|
|
||||||
header: {
|
|
||||||
fontSize: 36,
|
|
||||||
marginBottom: 48
|
|
||||||
},
|
|
||||||
textInput: {},
|
|
||||||
btnContainer: {
|
|
||||||
marginTop: 5,
|
|
||||||
marginBottom: 10,
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
export default withTheme(InsaHomeScreen);
|
|
||||||
|
|
@ -10,6 +10,8 @@ type Props = {
|
||||||
navigation: Object,
|
navigation: Object,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const LOGO = "https://etud.insa-toulouse.fr/~amicale_app/images/proximo-logo.png";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class defining the proximo about screen.
|
* Class defining the proximo about screen.
|
||||||
*/
|
*/
|
||||||
|
|
@ -27,9 +29,8 @@ export default class ProximoAboutScreen extends React.Component<Props> {
|
||||||
alignItems: 'center'
|
alignItems: 'center'
|
||||||
}}>
|
}}>
|
||||||
<Image
|
<Image
|
||||||
source={require('../../../assets/proximo-logo.png')}
|
source={{uri: LOGO}}
|
||||||
style={{flex: 1, resizeMode: "contain"}}
|
style={{height: '100%', width: '100%', resizeMode: "contain"}}/>
|
||||||
resizeMode="contain"/>
|
|
||||||
</View>
|
</View>
|
||||||
<Text>{i18n.t('proximoScreen.description')}</Text>
|
<Text>{i18n.t('proximoScreen.description')}</Text>
|
||||||
<Card style={{margin: 5}}>
|
<Card style={{margin: 5}}>
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,8 @@ type Props = {
|
||||||
navigation: Object,
|
navigation: Object,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const LOGO = "https://etud.insa-toulouse.fr/~amicale_app/images/proxiwash-logo.png";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class defining the proxiwash about screen.
|
* Class defining the proxiwash about screen.
|
||||||
*/
|
*/
|
||||||
|
|
@ -27,9 +29,8 @@ export default class ProxiwashAboutScreen extends React.Component<Props> {
|
||||||
alignItems: 'center'
|
alignItems: 'center'
|
||||||
}}>
|
}}>
|
||||||
<Image
|
<Image
|
||||||
source={require('../../../assets/proxiwash-logo.png')}
|
source={{uri: LOGO}}
|
||||||
style={{flex: 1, resizeMode: "contain"}}
|
style={{height: '100%', width: '100%', resizeMode: "contain"}}/>
|
||||||
resizeMode="contain"/>
|
|
||||||
</View>
|
</View>
|
||||||
<Text>{i18n.t('proxiwashScreen.description')}</Text>
|
<Text>{i18n.t('proxiwashScreen.description')}</Text>
|
||||||
<Card style={{margin: 5}}>
|
<Card style={{margin: 5}}>
|
||||||
|
|
|
||||||
291
src/screens/Services/ServicesScreen.js
Normal file
291
src/screens/Services/ServicesScreen.js
Normal file
|
|
@ -0,0 +1,291 @@
|
||||||
|
// @flow
|
||||||
|
|
||||||
|
import * as React from 'react';
|
||||||
|
import type {cardList} from "../../components/Lists/CardList/CardList";
|
||||||
|
import CardList from "../../components/Lists/CardList/CardList";
|
||||||
|
import CustomTabBar from "../../components/Tabbar/CustomTabBar";
|
||||||
|
import {withCollapsible} from "../../utils/withCollapsible";
|
||||||
|
import {Collapsible} from "react-navigation-collapsible";
|
||||||
|
import {CommonActions} from "@react-navigation/native";
|
||||||
|
import {Animated, View} from "react-native";
|
||||||
|
import {Avatar, Button, Card, Divider, List, Title, TouchableRipple, withTheme} from "react-native-paper";
|
||||||
|
import type {CustomTheme} from "../../managers/ThemeManager";
|
||||||
|
import ConnectionManager from "../../managers/ConnectionManager";
|
||||||
|
import i18n from 'i18n-js';
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
navigation: Object,
|
||||||
|
route: Object,
|
||||||
|
collapsibleStack: Collapsible,
|
||||||
|
theme: CustomTheme,
|
||||||
|
}
|
||||||
|
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";
|
||||||
|
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";
|
||||||
|
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";
|
||||||
|
const EMAIL_IMAGE = "https://etud-mel.insa-toulouse.fr/webmail/images/logo-bluemind.png";
|
||||||
|
const ENT_IMAGE = "https://ent.insa-toulouse.fr/media/org/jasig/portal/layout/tab-column/xhtml-theme/insa/institutional/LogoInsa.png";
|
||||||
|
|
||||||
|
const PROXIMO_IMAGE = "https://etud.insa-toulouse.fr/~amicale_app/images/proximo-logo.png"
|
||||||
|
const WIKETUD_LINK = "https://wiki.etud.insa-toulouse.fr/resources/assets/wiketud.png?ff051";
|
||||||
|
const AMICALE_IMAGE = require("../../../assets/amicale.png");
|
||||||
|
const EE_IMAGE = "https://etud.insa-toulouse.fr/~eeinsat/wp-content/uploads/2019/09/logo-blanc.png";
|
||||||
|
const TUTORINSA_IMAGE = "https://www.etud.insa-toulouse.fr/~tutorinsa/public/images/logo-gray.png";
|
||||||
|
|
||||||
|
export type listItem = {
|
||||||
|
title: string,
|
||||||
|
description: string,
|
||||||
|
image: string | number,
|
||||||
|
shouldLogin: boolean,
|
||||||
|
content: cardList,
|
||||||
|
}
|
||||||
|
|
||||||
|
type State = {
|
||||||
|
isLoggedIn: boolean,
|
||||||
|
}
|
||||||
|
|
||||||
|
class ServicesScreen extends React.Component<Props, State> {
|
||||||
|
|
||||||
|
amicaleDataset: cardList;
|
||||||
|
studentsDataset: cardList;
|
||||||
|
insaDataset: cardList;
|
||||||
|
|
||||||
|
finalDataset: Array<listItem>
|
||||||
|
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
const nav = props.navigation;
|
||||||
|
this.amicaleDataset = [
|
||||||
|
{
|
||||||
|
title: i18n.t('screens.clubsAbout'),
|
||||||
|
subtitle: "CLUB LIST",
|
||||||
|
image: AMICALE_IMAGE,
|
||||||
|
onPress: () => nav.navigate("club-list"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: i18n.t('screens.profile'),
|
||||||
|
subtitle: "PROFIL",
|
||||||
|
image: AMICALE_IMAGE,
|
||||||
|
onPress: () => nav.navigate("profile"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: i18n.t('screens.amicaleAbout'),
|
||||||
|
subtitle: "CONTACT",
|
||||||
|
image: AMICALE_IMAGE,
|
||||||
|
onPress: () => nav.navigate("amicale-contact"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: i18n.t('screens.vote'),
|
||||||
|
subtitle: "ELECTIONS",
|
||||||
|
image: AMICALE_IMAGE,
|
||||||
|
onPress: () => nav.navigate("vote"),
|
||||||
|
},
|
||||||
|
];
|
||||||
|
this.studentsDataset = [
|
||||||
|
{
|
||||||
|
title: i18n.t('screens.proximo'),
|
||||||
|
subtitle: "proximo",
|
||||||
|
image: PROXIMO_IMAGE,
|
||||||
|
onPress: () => nav.navigate("proximo"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: i18n.t('screens.amicaleWebsite'),
|
||||||
|
subtitle: "AMICALE",
|
||||||
|
image: AMICALE_IMAGE,
|
||||||
|
onPress: () => nav.navigate("amicale-website"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Wiketud",
|
||||||
|
subtitle: "wiketud",
|
||||||
|
image: WIKETUD_LINK,
|
||||||
|
onPress: () => nav.navigate("wiketud"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Élus Étudiants",
|
||||||
|
subtitle: "ELUS ETUDIANTS",
|
||||||
|
image: EE_IMAGE,
|
||||||
|
onPress: () => nav.navigate("elus-etudiants"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "Tutor'INSA",
|
||||||
|
subtitle: "TUTOR INSA",
|
||||||
|
image: TUTORINSA_IMAGE,
|
||||||
|
onPress: () => nav.navigate("tutorinsa"),
|
||||||
|
},
|
||||||
|
];
|
||||||
|
this.insaDataset = [
|
||||||
|
{
|
||||||
|
title: i18n.t('screens.menuSelf'),
|
||||||
|
subtitle: "the ru",
|
||||||
|
image: RU_IMAGE,
|
||||||
|
onPress: () => nav.navigate("self-menu"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: i18n.t('screens.availableRooms'),
|
||||||
|
subtitle: "ROOMS",
|
||||||
|
image: ROOM_IMAGE,
|
||||||
|
onPress: () => nav.navigate("available-rooms"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: i18n.t('screens.bib'),
|
||||||
|
subtitle: "BIB",
|
||||||
|
image: BIB_IMAGE,
|
||||||
|
onPress: () => nav.navigate("bib"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: i18n.t('screens.bluemind'),
|
||||||
|
subtitle: "EMAIL",
|
||||||
|
image: EMAIL_IMAGE,
|
||||||
|
onPress: () => nav.navigate("bluemind"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: i18n.t('screens.ent'),
|
||||||
|
subtitle: "ENT",
|
||||||
|
image: ENT_IMAGE,
|
||||||
|
onPress: () => nav.navigate("ent"),
|
||||||
|
},
|
||||||
|
];
|
||||||
|
this.finalDataset = [
|
||||||
|
{
|
||||||
|
title: i18n.t("servicesScreen.amicale"),
|
||||||
|
description: "LOGIN",
|
||||||
|
image: AMICALE_IMAGE,
|
||||||
|
shouldLogin: true,
|
||||||
|
content: this.amicaleDataset
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: i18n.t("servicesScreen.students"),
|
||||||
|
description: "SERVICES OFFERED BY STUDENTS",
|
||||||
|
image: 'account-group',
|
||||||
|
shouldLogin: false,
|
||||||
|
content: this.studentsDataset
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: i18n.t("servicesScreen.insa"),
|
||||||
|
description: "SERVICES OFFERED BY INSA",
|
||||||
|
image: 'school',
|
||||||
|
shouldLogin: false,
|
||||||
|
content: this.insaDataset
|
||||||
|
},
|
||||||
|
];
|
||||||
|
this.state = {
|
||||||
|
isLoggedIn: ConnectionManager.getInstance().isLoggedIn()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
this.props.navigation.addListener('focus', this.onFocus);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
onFocus = () => {
|
||||||
|
this.handleNavigationParams();
|
||||||
|
this.setState({isLoggedIn: ConnectionManager.getInstance().isLoggedIn()})
|
||||||
|
}
|
||||||
|
|
||||||
|
handleNavigationParams() {
|
||||||
|
if (this.props.route.params != null) {
|
||||||
|
if (this.props.route.params.nextScreen != null) {
|
||||||
|
this.props.navigation.navigate(this.props.route.params.nextScreen);
|
||||||
|
// reset params to prevent infinite loop
|
||||||
|
this.props.navigation.dispatch(CommonActions.setParams({nextScreen: null}));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
getAvatar(props, source: string | number) {
|
||||||
|
if (typeof source === "number")
|
||||||
|
return <Avatar.Image
|
||||||
|
{...props}
|
||||||
|
size={48}
|
||||||
|
source={AMICALE_IMAGE}
|
||||||
|
style={{backgroundColor: 'transparent'}}
|
||||||
|
/>
|
||||||
|
else
|
||||||
|
return <Avatar.Icon
|
||||||
|
{...props}
|
||||||
|
size={48}
|
||||||
|
icon={source}
|
||||||
|
color={this.props.theme.colors.primary}
|
||||||
|
style={{backgroundColor: 'transparent'}}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
|
||||||
|
getLoginMessage() {
|
||||||
|
return (
|
||||||
|
<View>
|
||||||
|
<Title style={{
|
||||||
|
marginLeft: 'auto',
|
||||||
|
marginRight: 'auto',
|
||||||
|
}}>
|
||||||
|
{i18n.t("servicesScreen.notLoggedIn")}
|
||||||
|
</Title>
|
||||||
|
<Button
|
||||||
|
icon="login"
|
||||||
|
mode="contained"
|
||||||
|
onPress={() => this.props.navigation.navigate("login")}
|
||||||
|
style={{
|
||||||
|
marginLeft: 'auto',
|
||||||
|
marginRight: 'auto',
|
||||||
|
}}>
|
||||||
|
{i18n.t("screens.login")}
|
||||||
|
</Button>
|
||||||
|
</View>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
renderItem = ({item}: { item: listItem }) => {
|
||||||
|
const shouldShowLogin = !this.state.isLoggedIn && item.shouldLogin;
|
||||||
|
return (
|
||||||
|
<TouchableRipple
|
||||||
|
style={{
|
||||||
|
margin: 5,
|
||||||
|
marginBottom: 20,
|
||||||
|
}}
|
||||||
|
onPress={shouldShowLogin
|
||||||
|
? undefined
|
||||||
|
: () => this.props.navigation.navigate("services-section", {data: item})}
|
||||||
|
>
|
||||||
|
<View>
|
||||||
|
<Card.Title
|
||||||
|
title={item.title}
|
||||||
|
left={(props) => this.getAvatar(props, item.image)}
|
||||||
|
right={shouldShowLogin
|
||||||
|
? undefined
|
||||||
|
: (props) => <List.Icon {...props} icon="chevron-right"/>}
|
||||||
|
/>
|
||||||
|
{
|
||||||
|
shouldShowLogin
|
||||||
|
? this.getLoginMessage()
|
||||||
|
: <CardList
|
||||||
|
dataset={item.content}
|
||||||
|
isHorizontal={true}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
</View>
|
||||||
|
</TouchableRipple>
|
||||||
|
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
keyExtractor = (item: listItem) => {
|
||||||
|
return item.title;
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const {containerPaddingTop, scrollIndicatorInsetTop, onScroll} = this.props.collapsibleStack;
|
||||||
|
return <Animated.FlatList
|
||||||
|
data={this.finalDataset}
|
||||||
|
renderItem={this.renderItem}
|
||||||
|
keyExtractor={this.keyExtractor}
|
||||||
|
onScroll={onScroll}
|
||||||
|
contentContainerStyle={{
|
||||||
|
paddingTop: containerPaddingTop,
|
||||||
|
paddingBottom: CustomTabBar.TAB_BAR_HEIGHT + 20
|
||||||
|
}}
|
||||||
|
scrollIndicatorInsets={{top: scrollIndicatorInsetTop}}
|
||||||
|
ItemSeparatorComponent={() => <Divider/>}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default withCollapsible(withTheme(ServicesScreen));
|
||||||
76
src/screens/Services/ServicesSectionScreen.js
Normal file
76
src/screens/Services/ServicesSectionScreen.js
Normal file
|
|
@ -0,0 +1,76 @@
|
||||||
|
// @flow
|
||||||
|
|
||||||
|
import * as React from 'react';
|
||||||
|
import CardList from "../../components/Lists/CardList/CardList";
|
||||||
|
import CustomTabBar from "../../components/Tabbar/CustomTabBar";
|
||||||
|
import {withCollapsible} from "../../utils/withCollapsible";
|
||||||
|
import {Collapsible} from "react-navigation-collapsible";
|
||||||
|
import {CommonActions} from "@react-navigation/native";
|
||||||
|
import ConnectionManager from "../../managers/ConnectionManager";
|
||||||
|
import type {listItem} from "./ServicesScreen";
|
||||||
|
import ErrorView from "../../components/Screens/ErrorView";
|
||||||
|
import {ERROR_TYPE} from "../../utils/WebData";
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
navigation: Object,
|
||||||
|
route: Object,
|
||||||
|
collapsibleStack: Collapsible,
|
||||||
|
}
|
||||||
|
|
||||||
|
type State = {
|
||||||
|
isLoggedIn: boolean,
|
||||||
|
}
|
||||||
|
|
||||||
|
class ServicesSectionScreen extends React.Component<Props, State> {
|
||||||
|
|
||||||
|
finalDataset: listItem;
|
||||||
|
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
this.handleNavigationParams();
|
||||||
|
this.state = {
|
||||||
|
isLoggedIn: ConnectionManager.getInstance().isLoggedIn(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
this.props.navigation.addListener('focus', this.onFocus);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
onFocus = () => {
|
||||||
|
this.setState({isLoggedIn: ConnectionManager.getInstance().isLoggedIn()})
|
||||||
|
}
|
||||||
|
|
||||||
|
handleNavigationParams() {
|
||||||
|
if (this.props.route.params != null) {
|
||||||
|
if (this.props.route.params.data != null) {
|
||||||
|
this.finalDataset = this.props.route.params.data;
|
||||||
|
// reset params to prevent infinite loop
|
||||||
|
this.props.navigation.dispatch(CommonActions.setParams({data: null}));
|
||||||
|
this.props.navigation.setOptions({
|
||||||
|
headerTitle: this.finalDataset.title,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const {containerPaddingTop, scrollIndicatorInsetTop, onScroll} = this.props.collapsibleStack;
|
||||||
|
if (!this.state.isLoggedIn && this.finalDataset.shouldLogin)
|
||||||
|
return <ErrorView {...this.props} errorCode={ERROR_TYPE.BAD_TOKEN}/>;
|
||||||
|
else
|
||||||
|
return <CardList
|
||||||
|
dataset={this.finalDataset.content}
|
||||||
|
isHorizontal={false}
|
||||||
|
onScroll={onScroll}
|
||||||
|
contentContainerStyle={{
|
||||||
|
paddingTop: containerPaddingTop,
|
||||||
|
paddingBottom: CustomTabBar.TAB_BAR_HEIGHT + 20
|
||||||
|
}}
|
||||||
|
scrollIndicatorInsets={{top: scrollIndicatorInsetTop}}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default withCollapsible(ServicesSectionScreen);
|
||||||
18
src/screens/Websites/BlueMindWebsiteScreen.js
Normal file
18
src/screens/Websites/BlueMindWebsiteScreen.js
Normal file
|
|
@ -0,0 +1,18 @@
|
||||||
|
// @flow
|
||||||
|
|
||||||
|
import * as React from 'react';
|
||||||
|
import WebViewScreen from "../../components/Screens/WebViewScreen";
|
||||||
|
|
||||||
|
const URL = 'https://etud-mel.insa-toulouse.fr/webmail/';
|
||||||
|
/**
|
||||||
|
* Class defining the app's available rooms screen.
|
||||||
|
* This screen uses a webview to render the page
|
||||||
|
*/
|
||||||
|
export const BlueMindWebsiteScreen = (props: Object) => {
|
||||||
|
return (
|
||||||
|
<WebViewScreen
|
||||||
|
{...props}
|
||||||
|
url={URL}/>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
18
src/screens/Websites/ENTWebsiteScreen.js
Normal file
18
src/screens/Websites/ENTWebsiteScreen.js
Normal file
|
|
@ -0,0 +1,18 @@
|
||||||
|
// @flow
|
||||||
|
|
||||||
|
import * as React from 'react';
|
||||||
|
import WebViewScreen from "../../components/Screens/WebViewScreen";
|
||||||
|
|
||||||
|
const URL = 'https://ent.insa-toulouse.fr/';
|
||||||
|
/**
|
||||||
|
* Class defining the app's available rooms screen.
|
||||||
|
* This screen uses a webview to render the page
|
||||||
|
*/
|
||||||
|
export const ENTWebsiteScreen = (props: Object) => {
|
||||||
|
return (
|
||||||
|
<WebViewScreen
|
||||||
|
{...props}
|
||||||
|
url={URL}/>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
@ -1,91 +0,0 @@
|
||||||
// @flow
|
|
||||||
|
|
||||||
import * as React from 'react';
|
|
||||||
import {ScrollView, StyleSheet} from "react-native";
|
|
||||||
import {Button, withTheme} from 'react-native-paper';
|
|
||||||
|
|
||||||
type Props = {
|
|
||||||
navigation: Object,
|
|
||||||
route: Object,
|
|
||||||
}
|
|
||||||
|
|
||||||
type State = {}
|
|
||||||
|
|
||||||
class WebsitesHomeScreen extends React.Component<Props, State> {
|
|
||||||
|
|
||||||
state = {};
|
|
||||||
|
|
||||||
colors: Object;
|
|
||||||
|
|
||||||
constructor(props) {
|
|
||||||
super(props);
|
|
||||||
|
|
||||||
this.colors = props.theme.colors;
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
|
||||||
const nav = this.props.navigation;
|
|
||||||
return (
|
|
||||||
<ScrollView>
|
|
||||||
<Button
|
|
||||||
icon={"information"}
|
|
||||||
onPress={() => nav.navigate("amicale-website")}
|
|
||||||
>
|
|
||||||
AMICALE
|
|
||||||
</Button>
|
|
||||||
<Button
|
|
||||||
icon={"information"}
|
|
||||||
onPress={() => nav.navigate("elus-etudiants")}
|
|
||||||
>
|
|
||||||
ELUS ETUDIANTS
|
|
||||||
</Button>
|
|
||||||
<Button
|
|
||||||
icon={"information"}
|
|
||||||
onPress={() => nav.navigate("tutorinsa")}
|
|
||||||
>
|
|
||||||
TUTOR INSA
|
|
||||||
</Button>
|
|
||||||
<Button
|
|
||||||
icon={"information"}
|
|
||||||
onPress={() => nav.navigate("wiketud")}
|
|
||||||
>
|
|
||||||
WIKETUD
|
|
||||||
</Button>
|
|
||||||
<Button
|
|
||||||
icon={"information"}
|
|
||||||
onPress={() => nav.navigate("proximo")}
|
|
||||||
>
|
|
||||||
PROXIMO
|
|
||||||
</Button>
|
|
||||||
<Button
|
|
||||||
icon={"information"}
|
|
||||||
onPress={() => nav.navigate("planning")}
|
|
||||||
>
|
|
||||||
PLANNING
|
|
||||||
</Button>
|
|
||||||
</ScrollView>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const styles = StyleSheet.create({
|
|
||||||
container: {
|
|
||||||
flex: 1,
|
|
||||||
flexDirection: 'column',
|
|
||||||
justifyContent: 'center',
|
|
||||||
},
|
|
||||||
card: {
|
|
||||||
margin: 10,
|
|
||||||
},
|
|
||||||
header: {
|
|
||||||
fontSize: 36,
|
|
||||||
marginBottom: 48
|
|
||||||
},
|
|
||||||
textInput: {},
|
|
||||||
btnContainer: {
|
|
||||||
marginTop: 5,
|
|
||||||
marginBottom: 10,
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
export default withTheme(WebsitesHomeScreen);
|
|
||||||
|
|
@ -1,13 +1,15 @@
|
||||||
{
|
{
|
||||||
"screens": {
|
"screens": {
|
||||||
"home": "Home",
|
"home": "Home",
|
||||||
"planning": "Planning",
|
"planning": "Events",
|
||||||
"planningDisplayScreen": "Event details",
|
"planningDisplayScreen": "Event details",
|
||||||
"clubDisplayScreen": "Club details",
|
"clubDisplayScreen": "Club details",
|
||||||
"feedDisplayScreen": "Details",
|
"feedDisplayScreen": "Details",
|
||||||
"clubsAbout": "Clubs",
|
"clubsAbout": "Clubs",
|
||||||
"amicaleAbout": "The Amicale",
|
"amicaleAbout": "Contact",
|
||||||
|
"amicaleWebsite": "Amicale's website",
|
||||||
"proxiwash": "Proxiwash",
|
"proxiwash": "Proxiwash",
|
||||||
|
"services": "Services",
|
||||||
"proximo": "Proximo",
|
"proximo": "Proximo",
|
||||||
"proximoArticles": "Articles",
|
"proximoArticles": "Articles",
|
||||||
"menuSelf": "RU Menu",
|
"menuSelf": "RU Menu",
|
||||||
|
|
@ -95,28 +97,11 @@
|
||||||
"todayEventsSubtitleNA": "No events today",
|
"todayEventsSubtitleNA": "No events today",
|
||||||
"todayEventsSubtitle": " event coming today",
|
"todayEventsSubtitle": " event coming today",
|
||||||
"todayEventsSubtitlePlural": " events coming today",
|
"todayEventsSubtitlePlural": " events coming today",
|
||||||
"proximoTitle": "Proximo",
|
"amicaleTitle": "The Amicale",
|
||||||
"proximoSubtitleNA": "No articles available",
|
"amicaleConnect": "Login",
|
||||||
"proximoSubtitle": " article available",
|
"amicaleConnected": "See available services"
|
||||||
"proximoSubtitlePlural": " articles available",
|
|
||||||
"tutorinsaSubtitleNA": "No tutorial available",
|
|
||||||
"tutorinsaSubtitle": " tutorial available",
|
|
||||||
"tutorinsaSubtitlePlural": " tutorials available",
|
|
||||||
"proxiwashTitle": "Available machines",
|
|
||||||
"proxiwashSubtitleNA": "No machines available",
|
|
||||||
"proxiwashSubtitle1": " dryer",
|
|
||||||
"proxiwashSubtitle1Plural": " dryers",
|
|
||||||
"proxiwashSubtitle2": " washer",
|
|
||||||
"proxiwashSubtitle2Plural": " washers",
|
|
||||||
"menuTitle": "Today's menu",
|
|
||||||
"menuSubtitleNA": "No menu available",
|
|
||||||
"menuSubtitle": "Click here to see the menu"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"planningScreen": {
|
|
||||||
"wipTitle": "WORK IN PROGRESS",
|
|
||||||
"wipSubtitle": "Soon, every event at the INSA Toulouse in one place !"
|
|
||||||
},
|
|
||||||
"aboutScreen": {
|
"aboutScreen": {
|
||||||
"appstore": "See on the Appstore",
|
"appstore": "See on the Appstore",
|
||||||
"playstore": "See on the Playstore",
|
"playstore": "See on the Playstore",
|
||||||
|
|
@ -397,5 +382,11 @@
|
||||||
"time": "Time: ",
|
"time": "Time: ",
|
||||||
"exit": "leave Game"
|
"exit": "leave Game"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"servicesScreen": {
|
||||||
|
"amicale": "The Amicale",
|
||||||
|
"students": "Student services",
|
||||||
|
"insa": "INSA services",
|
||||||
|
"notLoggedIn": "Not logged in"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,15 @@
|
||||||
{
|
{
|
||||||
"screens": {
|
"screens": {
|
||||||
"home": "Accueil",
|
"home": "Accueil",
|
||||||
"planning": "Planning",
|
"planning": "Événements",
|
||||||
"planningDisplayScreen": "Détails",
|
"planningDisplayScreen": "Détails",
|
||||||
"clubDisplayScreen": "Détails",
|
"clubDisplayScreen": "Détails",
|
||||||
"feedDisplayScreen": "Détails",
|
"feedDisplayScreen": "Détails",
|
||||||
"clubsAbout": "Les Clubs",
|
"clubsAbout": "Les Clubs",
|
||||||
"amicaleAbout": "L' Amicale",
|
"amicaleAbout": "Contact",
|
||||||
|
"amicaleWebsite": "Site de l'Amicale",
|
||||||
"proxiwash": "Proxiwash",
|
"proxiwash": "Proxiwash",
|
||||||
|
"services": "Services",
|
||||||
"proximo": "Proximo",
|
"proximo": "Proximo",
|
||||||
"proximoArticles": "Articles",
|
"proximoArticles": "Articles",
|
||||||
"menuSelf": "Menu du RU",
|
"menuSelf": "Menu du RU",
|
||||||
|
|
@ -95,28 +97,11 @@
|
||||||
"todayEventsSubtitleNA": "Pas d'événement",
|
"todayEventsSubtitleNA": "Pas d'événement",
|
||||||
"todayEventsSubtitle": " événement aujourd'hui",
|
"todayEventsSubtitle": " événement aujourd'hui",
|
||||||
"todayEventsSubtitlePlural": " événements aujourd'hui",
|
"todayEventsSubtitlePlural": " événements aujourd'hui",
|
||||||
"proximoTitle": "Proximo",
|
"amicaleTitle": "L'Amicale",
|
||||||
"proximoSubtitleNA": "pas d'article en vente",
|
"amicaleConnect": "Se connecter",
|
||||||
"proximoSubtitle": " article disponible",
|
"amicaleConnected": "Voir les services disponibles"
|
||||||
"proximoSubtitlePlural": " articles disponibles",
|
|
||||||
"tutorinsaSubtitleNA": "Aucun tutorat disponible",
|
|
||||||
"tutorinsaSubtitle": " tutorat disponible",
|
|
||||||
"tutorinsaSubtitlePlural": " tutorats disponibles",
|
|
||||||
"proxiwashTitle": "Machines disponibles",
|
|
||||||
"proxiwashSubtitleNA": "Pas de machine disponible",
|
|
||||||
"proxiwashSubtitle1": " sèche-linge",
|
|
||||||
"proxiwashSubtitle1Plural": " sèche-linges",
|
|
||||||
"proxiwashSubtitle2": " lave-linge",
|
|
||||||
"proxiwashSubtitle2Plural": " lave-linges",
|
|
||||||
"menuTitle": "Menu d'aujourd'hui",
|
|
||||||
"menuSubtitleNA": "Pas de menu disponible",
|
|
||||||
"menuSubtitle": "Cliquez ici pour voir le menu"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"planningScreen": {
|
|
||||||
"wipTitle": "WORK IN PROGRESS",
|
|
||||||
"wipSubtitle": "Bientôt, tous les évènements de l'INSA Toulouse en un seul endroit !"
|
|
||||||
},
|
|
||||||
"aboutScreen": {
|
"aboutScreen": {
|
||||||
"appstore": "Voir sur l'Appstore",
|
"appstore": "Voir sur l'Appstore",
|
||||||
"playstore": "Voir sur le Playstore",
|
"playstore": "Voir sur le Playstore",
|
||||||
|
|
@ -397,5 +382,11 @@
|
||||||
"time": "Temps: ",
|
"time": "Temps: ",
|
||||||
"exit": "Quitter"
|
"exit": "Quitter"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"servicesScreen": {
|
||||||
|
"amicale": "L'Amicale",
|
||||||
|
"students": "Services étudiants",
|
||||||
|
"insa": "Services de l'INSA",
|
||||||
|
"notLoggedIn": "Non connecté"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue