diff --git a/components/Sidebar/Sidebar.js b/components/Sidebar/Sidebar.js index c104205..80d9b33 100644 --- a/components/Sidebar/Sidebar.js +++ b/components/Sidebar/Sidebar.js @@ -64,6 +64,12 @@ class SideBar extends React.PureComponent { icon: "account", onlyWhenLoggedIn: true, }, + { + name: "CLUBS", + route: "ClubListScreen", + icon: "account-group", + onlyWhenLoggedIn: true, + }, { name: i18n.t('screens.logout'), route: 'disconnect', diff --git a/navigation/DrawerNavigator.js b/navigation/DrawerNavigator.js index b014aa5..943b3d6 100644 --- a/navigation/DrawerNavigator.js +++ b/navigation/DrawerNavigator.js @@ -17,6 +17,8 @@ import HeaderButton from "../components/Custom/HeaderButton"; import i18n from "i18n-js"; import LoginScreen from "../screens/Amicale/LoginScreen"; import ProfileScreen from "../screens/Amicale/ProfileScreen"; +import ClubListScreen from "../screens/Amicale/ClubListScreen"; +import ClubDisplayScreen from "../screens/Amicale/ClubDisplayScreen"; const defaultScreenOptions = { gestureEnabled: true, @@ -236,6 +238,43 @@ function ProfileStackComponent() { ); } +const ClubStack = createStackNavigator(); + +function ClubStackComponent() { + return ( + + { + const openDrawer = getDrawerButton.bind(this, navigation); + return { + title: "CLUBS LIST", + headerLeft: openDrawer + }; + }} + /> + { + const openDrawer = getDrawerButton.bind(this, navigation); + return { + title: "CLUBS DISPLAY", + headerLeft: openDrawer, + ...TransitionPresets.ModalSlideFromBottomIOS, + }; + }} + /> + + ); +} + + const Drawer = createDrawerNavigator(); function getDrawerContent(props) { @@ -289,6 +328,10 @@ export default function DrawerNavigator() { name="ProfileScreen" component={ProfileStackComponent} /> + ); } diff --git a/screens/Amicale/ClubDisplayScreen.js b/screens/Amicale/ClubDisplayScreen.js new file mode 100644 index 0000000..ed09b9d --- /dev/null +++ b/screens/Amicale/ClubDisplayScreen.js @@ -0,0 +1,113 @@ +// @flow + +import * as React from 'react'; +import {Image, ScrollView, TouchableOpacity, View} from 'react-native'; +import HTML from "react-native-render-html"; +import {Linking} from "expo"; +import {Avatar, Card, Paragraph, Portal, withTheme} from 'react-native-paper'; +import ImageView from "react-native-image-viewing"; + +type Props = { + navigation: Object, + route: Object +}; + +type State = { + imageModalVisible: boolean, +}; + +function openWebLink(event, link) { + Linking.openURL(link).catch((err) => console.error('Error opening link', err)); +} + +/** + * Class defining a planning event information page. + */ +class ClubDisplayScreen extends React.Component { + + displayData = this.props.route.params['data']; + + colors: Object; + + state = { + imageModalVisible: false, + }; + + constructor(props) { + super(props); + this.colors = props.theme.colors; + } + + componentDidMount(): * { + this.props.navigation.setOptions({title: this.displayData.name}) + } + + showImageModal = () => { + this.setState({imageModalVisible: true}); + }; + + hideImageModal = () => { + this.setState({imageModalVisible: false}); + }; + + getResponsiblesRender(resp: Array) { + let final = []; + for (let i = 0; i < resp.length; i++) { + final.push({resp[i]}) + } + return ( + + } + /> + + {final} + + + ); + } + + render() { + return ( + + {this.displayData.logo !== null ? + + + + : } + + {this.displayData.description !== null ? + // Surround description with div to allow text styling if the description is not html + + " + this.displayData.description + ""} + tagsStyles={{ + p: {color: this.colors.text,}, + div: {color: this.colors.text} + }} + onLinkPress={openWebLink}/> + + : } + {this.getResponsiblesRender(this.displayData.responsibles)} + + + + + ); + } +} + +export default withTheme(ClubDisplayScreen); diff --git a/screens/Amicale/ClubListScreen.js b/screens/Amicale/ClubListScreen.js new file mode 100644 index 0000000..a31c31a --- /dev/null +++ b/screens/Amicale/ClubListScreen.js @@ -0,0 +1,102 @@ +// @flow + +import * as React from 'react'; +import {View} from "react-native"; +import {Avatar, Chip, List, withTheme} from 'react-native-paper'; +import AuthenticatedScreen from "../../components/Amicale/AuthenticatedScreen"; +import PureFlatList from "../../components/Lists/PureFlatList"; + +type Props = { + navigation: Object, + theme: Object, +} + +type State = {} + +class ClubListScreen extends React.Component { + + state = {}; + + colors: Object; + + getRenderItem: Function; + + categories: Array; + + constructor(props) { + super(props); + this.colors = props.theme.colors; + } + + keyExtractor = (item: Object) => { + return item.name + item.logo; + }; + + getScreen = (data: Object) => { + this.categories = data.categories; + return ( + + ) + }; + + getCategoryName(id: number) { + for (let i = 0; i < this.categories.length; i++) { + if (id === this.categories[i].id) + return this.categories[i].name; + } + return ""; + } + + getCategoriesRender(categories: Array) { + let final = []; + for (let i = 0; i < categories.length; i++) { + if (categories[i] !== null) + final.push({this.getCategoryName(categories[i])}); + } + return {final}; + } + + getRenderItem = ({item}: Object) => { + const onPress = this.onListItemPress.bind(this, item); + const categoriesRender = this.getCategoriesRender.bind(this, item.category); + return ( + } + /> + ); + }; + + /** + * Callback used when clicking an article in the list. + * It opens the modal to show detailed information about the article + * + * @param item The article pressed + */ + onListItemPress(item: Object) { + this.props.navigation.navigate("ClubDisplayScreen", {data: item}); + } + + render() { + return ( + + ); + } +} + +export default withTheme(ClubListScreen);