forked from vergnet/application-amicale
Added contact link
This commit is contained in:
parent
b7d6c98025
commit
c4337b13cb
4 changed files with 95 additions and 55 deletions
|
@ -2,22 +2,35 @@
|
||||||
|
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import {ScrollView, View} from 'react-native';
|
import {ScrollView, View} from 'react-native';
|
||||||
import {Avatar, Card, Chip, Paragraph, withTheme} from 'react-native-paper';
|
import {Avatar, Button, Card, Chip, Paragraph, withTheme} from 'react-native-paper';
|
||||||
import ImageModal from 'react-native-image-modal';
|
import ImageModal from 'react-native-image-modal';
|
||||||
import i18n from "i18n-js";
|
import i18n from "i18n-js";
|
||||||
import AuthenticatedScreen from "../../../components/Amicale/AuthenticatedScreen";
|
import AuthenticatedScreen from "../../../components/Amicale/AuthenticatedScreen";
|
||||||
import CustomHTML from "../../../components/Overrides/CustomHTML";
|
import CustomHTML from "../../../components/Overrides/CustomHTML";
|
||||||
import CustomTabBar from "../../../components/Tabbar/CustomTabBar";
|
import CustomTabBar from "../../../components/Tabbar/CustomTabBar";
|
||||||
|
import type {category, club} from "./ClubListScreen";
|
||||||
|
import type {CustomTheme} from "../../../managers/ThemeManager";
|
||||||
|
import {StackNavigationProp} from "@react-navigation/stack";
|
||||||
|
import {Linking} from "expo";
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
navigation: Object,
|
navigation: StackNavigationProp,
|
||||||
route: Object
|
route: {
|
||||||
|
params?: {
|
||||||
|
data?: club,
|
||||||
|
categories?: Array<category>,
|
||||||
|
clubId?: number,
|
||||||
|
}, ...
|
||||||
|
},
|
||||||
|
theme: CustomTheme
|
||||||
};
|
};
|
||||||
|
|
||||||
type State = {
|
type State = {
|
||||||
imageModalVisible: boolean,
|
imageModalVisible: boolean,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const AMICALE_MAIL = "clubs@amicale-insat.fr";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class defining a club event information page.
|
* Class defining a club event information page.
|
||||||
* If called with data and categories navigation parameters, will use those to display the data.
|
* If called with data and categories navigation parameters, will use those to display the data.
|
||||||
|
@ -25,32 +38,30 @@ type State = {
|
||||||
*/
|
*/
|
||||||
class ClubDisplayScreen extends React.Component<Props, State> {
|
class ClubDisplayScreen extends React.Component<Props, State> {
|
||||||
|
|
||||||
displayData: Object;
|
displayData: club | null;
|
||||||
categories: Object | null;
|
categories: Array<category> | null;
|
||||||
clubId: number;
|
clubId: number;
|
||||||
|
|
||||||
shouldFetchData: boolean;
|
shouldFetchData: boolean;
|
||||||
|
|
||||||
colors: Object;
|
|
||||||
|
|
||||||
state = {
|
state = {
|
||||||
imageModalVisible: false,
|
imageModalVisible: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
this.colors = props.theme.colors;
|
if (this.props.route.params != null) {
|
||||||
|
if (this.props.route.params.data != null && this.props.route.params.categories != null) {
|
||||||
if (this.props.route.params.data !== undefined && this.props.route.params.categories !== undefined) {
|
this.displayData = this.props.route.params.data;
|
||||||
this.displayData = this.props.route.params.data;
|
this.categories = this.props.route.params.categories;
|
||||||
this.categories = this.props.route.params.categories;
|
this.clubId = this.props.route.params.data.id;
|
||||||
this.clubId = this.props.route.params.data.id;
|
this.shouldFetchData = false;
|
||||||
this.shouldFetchData = false;
|
} else if (this.props.route.params.clubId != null) {
|
||||||
} else {
|
this.displayData = null;
|
||||||
this.displayData = null;
|
this.categories = null;
|
||||||
this.categories = null;
|
this.clubId = this.props.route.params.clubId;
|
||||||
this.clubId = this.props.route.params.clubId;
|
this.shouldFetchData = true;
|
||||||
this.shouldFetchData = true;
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -64,7 +75,7 @@ class ClubDisplayScreen extends React.Component<Props, State> {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
getCategoriesRender(categories: Array<number | null>) {
|
getCategoriesRender(categories: [number, number]) {
|
||||||
if (this.categories === null)
|
if (this.categories === null)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
|
@ -84,7 +95,7 @@ class ClubDisplayScreen extends React.Component<Props, State> {
|
||||||
return <View style={{flexDirection: 'row', marginTop: 5}}>{final}</View>;
|
return <View style={{flexDirection: 'row', marginTop: 5}}>{final}</View>;
|
||||||
}
|
}
|
||||||
|
|
||||||
getManagersRender(resp: Array<string>) {
|
getManagersRender(resp: Array<string>, email: string | null) {
|
||||||
let final = [];
|
let final = [];
|
||||||
for (let i = 0; i < resp.length; i++) {
|
for (let i = 0; i < resp.length; i++) {
|
||||||
final.push(<Paragraph key={i.toString()}>{resp[i]}</Paragraph>)
|
final.push(<Paragraph key={i.toString()}>{resp[i]}</Paragraph>)
|
||||||
|
@ -98,56 +109,81 @@ class ClubDisplayScreen extends React.Component<Props, State> {
|
||||||
left={(props) => <Avatar.Icon
|
left={(props) => <Avatar.Icon
|
||||||
{...props}
|
{...props}
|
||||||
style={{backgroundColor: 'transparent'}}
|
style={{backgroundColor: 'transparent'}}
|
||||||
color={hasManagers ? this.colors.success : this.colors.primary}
|
color={hasManagers ? this.props.theme.colors.success : this.props.theme.colors.primary}
|
||||||
icon="account-tie"/>}
|
icon="account-tie"/>}
|
||||||
/>
|
/>
|
||||||
<Card.Content>
|
<Card.Content>
|
||||||
{final}
|
{final}
|
||||||
|
{this.getEmailButton(email, hasManagers)}
|
||||||
</Card.Content>
|
</Card.Content>
|
||||||
</Card>
|
</Card>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getEmailButton(email: string | null, hasManagers: boolean) {
|
||||||
|
const destinationEmail = email != null && hasManagers
|
||||||
|
? email
|
||||||
|
: AMICALE_MAIL;
|
||||||
|
const text = email != null && hasManagers
|
||||||
|
? i18n.t("clubs.clubContact")
|
||||||
|
: i18n.t("clubs.amicaleContact");
|
||||||
|
return (
|
||||||
|
<Card.Actions>
|
||||||
|
<Button
|
||||||
|
icon="email"
|
||||||
|
mode="contained"
|
||||||
|
onPress={() => Linking.openURL('mailto:' + destinationEmail)}
|
||||||
|
style={{marginLeft: 'auto'}}
|
||||||
|
>
|
||||||
|
{text}
|
||||||
|
</Button>
|
||||||
|
</Card.Actions>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
updateHeaderTitle(data: Object) {
|
updateHeaderTitle(data: Object) {
|
||||||
this.props.navigation.setOptions({title: data.name})
|
this.props.navigation.setOptions({title: data.name})
|
||||||
}
|
}
|
||||||
|
|
||||||
getScreen = (response: Array<Object>) => {
|
getScreen = (response: Array<Object>) => {
|
||||||
let data = response[0];
|
let data: club = response[0];
|
||||||
this.updateHeaderTitle(data);
|
this.updateHeaderTitle(data);
|
||||||
|
if (data != null) {
|
||||||
|
return (
|
||||||
|
<ScrollView style={{paddingLeft: 5, paddingRight: 5}}>
|
||||||
|
{this.getCategoriesRender(data.category)}
|
||||||
|
{data.logo !== null ?
|
||||||
|
<View style={{
|
||||||
|
marginLeft: 'auto',
|
||||||
|
marginRight: 'auto',
|
||||||
|
marginTop: 10,
|
||||||
|
marginBottom: 10,
|
||||||
|
}}>
|
||||||
|
<ImageModal
|
||||||
|
resizeMode="contain"
|
||||||
|
imageBackgroundColor={this.props.theme.colors.background}
|
||||||
|
style={{
|
||||||
|
width: 300,
|
||||||
|
height: 300,
|
||||||
|
}}
|
||||||
|
source={{
|
||||||
|
uri: data.logo,
|
||||||
|
}}
|
||||||
|
/></View>
|
||||||
|
: <View/>}
|
||||||
|
|
||||||
return (
|
{data.description !== null ?
|
||||||
<ScrollView style={{paddingLeft: 5, paddingRight: 5}}>
|
// Surround description with div to allow text styling if the description is not html
|
||||||
{this.getCategoriesRender(data.category)}
|
<Card.Content>
|
||||||
{data.logo !== null ?
|
<CustomHTML html={data.description}/>
|
||||||
<View style={{
|
</Card.Content>
|
||||||
marginLeft: 'auto',
|
: <View/>}
|
||||||
marginRight: 'auto',
|
{this.getManagersRender(data.responsibles, data.email)}
|
||||||
marginTop: 10,
|
</ScrollView>
|
||||||
marginBottom: 10,
|
);
|
||||||
}}>
|
} else
|
||||||
<ImageModal
|
return null;
|
||||||
resizeMode="contain"
|
|
||||||
imageBackgroundColor={this.colors.background}
|
|
||||||
style={{
|
|
||||||
width: 300,
|
|
||||||
height: 300,
|
|
||||||
}}
|
|
||||||
source={{
|
|
||||||
uri: data.logo,
|
|
||||||
}}
|
|
||||||
/></View>
|
|
||||||
: <View/>}
|
|
||||||
|
|
||||||
{data.description !== null ?
|
|
||||||
// Surround description with div to allow text styling if the description is not html
|
|
||||||
<Card.Content>
|
|
||||||
<CustomHTML html={data.description}/>
|
|
||||||
</Card.Content>
|
|
||||||
: <View/>}
|
|
||||||
{this.getManagersRender(data.responsibles)}
|
|
||||||
</ScrollView>
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
|
|
@ -24,7 +24,7 @@ export type club = {
|
||||||
name: string,
|
name: string,
|
||||||
description: string,
|
description: string,
|
||||||
logo: string,
|
logo: string,
|
||||||
email:string,
|
email: string | null,
|
||||||
category: [number, number],
|
category: [number, number],
|
||||||
responsibles: Array<string>,
|
responsibles: Array<string>,
|
||||||
};
|
};
|
||||||
|
|
|
@ -261,6 +261,8 @@
|
||||||
"managersUnavailable": "This club has no one :(",
|
"managersUnavailable": "This club has no one :(",
|
||||||
"categories": "Categories",
|
"categories": "Categories",
|
||||||
"categoriesFilterMessage": "Click on a category to filter the list",
|
"categoriesFilterMessage": "Click on a category to filter the list",
|
||||||
|
"clubContact": "Contact the club",
|
||||||
|
"amicaleContact": "Contact the Amicale",
|
||||||
"about": {
|
"about": {
|
||||||
"text": "The clubs, making the campus live, with more than sixty clubs offering various activities! From the philosophy club to the PABI (Production Artisanale de Bière Insaienne), without forgetting the multiple music and dance clubs, you will surely find an activity that suits you!",
|
"text": "The clubs, making the campus live, with more than sixty clubs offering various activities! From the philosophy club to the PABI (Production Artisanale de Bière Insaienne), without forgetting the multiple music and dance clubs, you will surely find an activity that suits you!",
|
||||||
"title": "A question ?",
|
"title": "A question ?",
|
||||||
|
|
|
@ -261,6 +261,8 @@
|
||||||
"managersUnavailable": "Ce club est tout seul :(",
|
"managersUnavailable": "Ce club est tout seul :(",
|
||||||
"categories": "Catégories",
|
"categories": "Catégories",
|
||||||
"categoriesFilterMessage": "Cliquez sur une catégorie pour filtrer la liste",
|
"categoriesFilterMessage": "Cliquez sur une catégorie pour filtrer la liste",
|
||||||
|
"clubContact": "Contacter le club",
|
||||||
|
"amicaleContact": "Contacter l'Amicale",
|
||||||
"about": {
|
"about": {
|
||||||
"text": "Les clubs, c'est ce qui fait vivre le campus au quotidien, plus d'une soixantaine de clubs qui proposent des activités diverses et variées ! Du club Philosophie au PABI (Production Artisanale de Bière Insaienne), en passant par les multiples clubs de musique et de danse, vous trouverez forcément une activité qui vous permettra de vous épanouir sur le campus !",
|
"text": "Les clubs, c'est ce qui fait vivre le campus au quotidien, plus d'une soixantaine de clubs qui proposent des activités diverses et variées ! Du club Philosophie au PABI (Production Artisanale de Bière Insaienne), en passant par les multiples clubs de musique et de danse, vous trouverez forcément une activité qui vous permettra de vous épanouir sur le campus !",
|
||||||
"title": "Une question ?",
|
"title": "Une question ?",
|
||||||
|
|
Loading…
Reference in a new issue