Compare commits
4 commits
cbb0624189
...
4f80cadfed
| Author | SHA1 | Date | |
|---|---|---|---|
| 4f80cadfed | |||
| f282a1dd84 | |||
| 9bdfe3944e | |||
| 9f391fc335 |
10 changed files with 134 additions and 120 deletions
|
|
@ -1,46 +1,60 @@
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
|
import {View} from "react-native";
|
||||||
import {withTheme} from 'react-native-paper';
|
import {withTheme} from 'react-native-paper';
|
||||||
import {Agenda} from "react-native-calendars";
|
import {Agenda} from "react-native-calendars";
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
theme: Object,
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Abstraction layer for Agenda component, using custom configuration
|
* Abstraction layer for Agenda component, using custom configuration
|
||||||
*
|
|
||||||
* @param props Props to pass to the element. Must specify an onRef prop to get an Agenda ref.
|
|
||||||
* @return {*}
|
|
||||||
*/
|
*/
|
||||||
function CustomAgenda(props) {
|
class CustomAgenda extends React.Component<Props> {
|
||||||
const {colors} = props.theme;
|
|
||||||
return (
|
getAgenda() {
|
||||||
<Agenda
|
return <Agenda
|
||||||
{...props}
|
{...this.props}
|
||||||
ref={props.onRef}
|
ref={this.props.onRef}
|
||||||
theme={{
|
theme={{
|
||||||
backgroundColor: colors.agendaBackgroundColor,
|
backgroundColor: this.props.theme.colors.agendaBackgroundColor,
|
||||||
calendarBackground: colors.background,
|
calendarBackground: this.props.theme.colors.background,
|
||||||
textSectionTitleColor: colors.agendaDayTextColor,
|
textSectionTitleColor: this.props.theme.colors.agendaDayTextColor,
|
||||||
selectedDayBackgroundColor: colors.primary,
|
selectedDayBackgroundColor: this.props.theme.colors.primary,
|
||||||
selectedDayTextColor: '#ffffff',
|
selectedDayTextColor: '#ffffff',
|
||||||
todayTextColor: colors.primary,
|
todayTextColor: this.props.theme.colors.primary,
|
||||||
dayTextColor: colors.text,
|
dayTextColor: this.props.theme.colors.text,
|
||||||
textDisabledColor: colors.agendaDayTextColor,
|
textDisabledColor: this.props.theme.colors.agendaDayTextColor,
|
||||||
dotColor: colors.primary,
|
dotColor: this.props.theme.colors.primary,
|
||||||
selectedDotColor: '#ffffff',
|
selectedDotColor: '#ffffff',
|
||||||
arrowColor: 'orange',
|
arrowColor: 'orange',
|
||||||
monthTextColor: colors.primary,
|
monthTextColor: this.props.theme.colors.primary,
|
||||||
indicatorColor: colors.primary,
|
indicatorColor: this.props.theme.colors.primary,
|
||||||
textDayFontWeight: '300',
|
textDayFontWeight: '300',
|
||||||
textMonthFontWeight: 'bold',
|
textMonthFontWeight: 'bold',
|
||||||
textDayHeaderFontWeight: '300',
|
textDayHeaderFontWeight: '300',
|
||||||
textDayFontSize: 16,
|
textDayFontSize: 16,
|
||||||
textMonthFontSize: 16,
|
textMonthFontSize: 16,
|
||||||
textDayHeaderFontSize: 16,
|
textDayHeaderFontSize: 16,
|
||||||
agendaDayTextColor: colors.agendaDayTextColor,
|
agendaDayTextColor: this.props.theme.colors.agendaDayTextColor,
|
||||||
agendaDayNumColor: colors.agendaDayTextColor,
|
agendaDayNumColor: this.props.theme.colors.agendaDayTextColor,
|
||||||
agendaTodayColor: colors.primary,
|
agendaTodayColor: this.props.theme.colors.primary,
|
||||||
agendaKnobColor: colors.primary,
|
agendaKnobColor: this.props.theme.colors.primary,
|
||||||
}}
|
}}
|
||||||
/>
|
/>;
|
||||||
);
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
// Completely recreate the component on theme change to force theme reload
|
||||||
|
if (this.props.theme.dark)
|
||||||
|
return (
|
||||||
|
<View style={{flex: 1}}>
|
||||||
|
{this.getAgenda()}
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
else
|
||||||
|
return this.getAgenda();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default withTheme(CustomAgenda);
|
export default withTheme(CustomAgenda);
|
||||||
|
|
|
||||||
44
src/components/Custom/CustomHTML.js
Normal file
44
src/components/Custom/CustomHTML.js
Normal file
|
|
@ -0,0 +1,44 @@
|
||||||
|
import * as React from 'react';
|
||||||
|
import {View} from "react-native";
|
||||||
|
import {withTheme} from 'react-native-paper';
|
||||||
|
import HTML from "react-native-render-html";
|
||||||
|
import {Linking} from "expo";
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
theme: Object,
|
||||||
|
html: string,
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Abstraction layer for Agenda component, using custom configuration
|
||||||
|
*/
|
||||||
|
class CustomHTML extends React.Component<Props> {
|
||||||
|
|
||||||
|
openWebLink = (event, link) => {
|
||||||
|
Linking.openURL(link).catch((err) => console.error('Error opening link', err));
|
||||||
|
};
|
||||||
|
|
||||||
|
getHTML() {
|
||||||
|
// Surround description with div to allow text styling if the description is not html
|
||||||
|
return <HTML html={"<div>" + this.props.html + "</div>"}
|
||||||
|
tagsStyles={{
|
||||||
|
p: {color: this.props.theme.colors.text},
|
||||||
|
div: {color: this.props.theme.colors.text}
|
||||||
|
}}
|
||||||
|
onLinkPress={this.openWebLink}/>;
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
// Completely recreate the component on theme change to force theme reload
|
||||||
|
if (this.props.theme.dark)
|
||||||
|
return (
|
||||||
|
<View>
|
||||||
|
{this.getHTML()}
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
else
|
||||||
|
return this.getHTML();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default withTheme(CustomHTML);
|
||||||
|
|
@ -2,10 +2,10 @@
|
||||||
|
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import {StyleSheet, View} from "react-native";
|
import {StyleSheet, View} from "react-native";
|
||||||
import HTML from "react-native-render-html";
|
|
||||||
import i18n from "i18n-js";
|
import i18n from "i18n-js";
|
||||||
import {Avatar, Button, Card, withTheme} from 'react-native-paper';
|
import {Avatar, Button, Card} from 'react-native-paper';
|
||||||
import {getFormattedEventTime, isDescriptionEmpty} from "../../utils/Planning";
|
import {getFormattedEventTime, isDescriptionEmpty} from "../../utils/Planning";
|
||||||
|
import CustomHTML from "../Custom/CustomHTML";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Component used to display an event preview if an event is available
|
* Component used to display an event preview if an event is available
|
||||||
|
|
@ -13,8 +13,7 @@ import {getFormattedEventTime, isDescriptionEmpty} from "../../utils/Planning";
|
||||||
* @param props Props to pass to the component
|
* @param props Props to pass to the component
|
||||||
* @return {*}
|
* @return {*}
|
||||||
*/
|
*/
|
||||||
function PreviewEventDashboardItem(props) {
|
function PreviewEventDashboardItem(props : Object) {
|
||||||
const {colors} = props.theme;
|
|
||||||
const isEmpty = props.event === undefined
|
const isEmpty = props.event === undefined
|
||||||
? true
|
? true
|
||||||
: isDescriptionEmpty(props.event['description']);
|
: isDescriptionEmpty(props.event['description']);
|
||||||
|
|
@ -43,12 +42,7 @@ function PreviewEventDashboardItem(props) {
|
||||||
/>}
|
/>}
|
||||||
{!isEmpty ?
|
{!isEmpty ?
|
||||||
<Card.Content style={styles.content}>
|
<Card.Content style={styles.content}>
|
||||||
<HTML html={"<div>" + props.event['description'] + "</div>"}
|
<CustomHTML html={props.event['description']}/>
|
||||||
tagsStyles={{
|
|
||||||
p: {color: colors.text,},
|
|
||||||
div: {color: colors.text},
|
|
||||||
}}/>
|
|
||||||
|
|
||||||
</Card.Content> : null}
|
</Card.Content> : null}
|
||||||
|
|
||||||
<Card.Actions style={styles.actions}>
|
<Card.Actions style={styles.actions}>
|
||||||
|
|
@ -82,4 +76,4 @@ const styles = StyleSheet.create({
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
export default withTheme(PreviewEventDashboardItem);
|
export default PreviewEventDashboardItem;
|
||||||
|
|
|
||||||
|
|
@ -234,13 +234,11 @@ type Props = {
|
||||||
class TabNavigator extends React.Component<Props>{
|
class TabNavigator extends React.Component<Props>{
|
||||||
|
|
||||||
createHomeStackComponent: Object;
|
createHomeStackComponent: Object;
|
||||||
colors: Object;
|
|
||||||
|
|
||||||
defaultRoute: string;
|
defaultRoute: string;
|
||||||
|
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
this.colors = props.theme.colors;
|
|
||||||
this.defaultRoute = AsyncStorageManager.getInstance().preferences.defaultStartScreen.current.toLowerCase();
|
this.defaultRoute = AsyncStorageManager.getInstance().preferences.defaultStartScreen.current.toLowerCase();
|
||||||
|
|
||||||
if (props.defaultRoute !== null)
|
if (props.defaultRoute !== null)
|
||||||
|
|
@ -253,7 +251,7 @@ class TabNavigator extends React.Component<Props>{
|
||||||
return (
|
return (
|
||||||
<Tab.Navigator
|
<Tab.Navigator
|
||||||
initialRouteName={this.defaultRoute}
|
initialRouteName={this.defaultRoute}
|
||||||
barStyle={{backgroundColor: this.colors.surface}}
|
barStyle={{backgroundColor: this.props.theme.colors.surface}}
|
||||||
screenOptions={({route}) => ({
|
screenOptions={({route}) => ({
|
||||||
tabBarIcon: ({focused, color, size}) => {
|
tabBarIcon: ({focused, color, size}) => {
|
||||||
let icon = TAB_ICONS[route.name];
|
let icon = TAB_ICONS[route.name];
|
||||||
|
|
@ -262,8 +260,8 @@ class TabNavigator extends React.Component<Props>{
|
||||||
return <MaterialCommunityIcons name={icon} color={color} size={26}/>;
|
return <MaterialCommunityIcons name={icon} color={color} size={26}/>;
|
||||||
},
|
},
|
||||||
})}
|
})}
|
||||||
activeColor={this.colors.primary}
|
activeColor={this.props.theme.colors.primary}
|
||||||
inactiveColor={this.colors.tabIcon}
|
inactiveColor={this.props.theme.colors.tabIcon}
|
||||||
>
|
>
|
||||||
<Tab.Screen
|
<Tab.Screen
|
||||||
name="proximo"
|
name="proximo"
|
||||||
|
|
|
||||||
|
|
@ -2,12 +2,11 @@
|
||||||
|
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import {ScrollView, View} from 'react-native';
|
import {ScrollView, View} from 'react-native';
|
||||||
import HTML from "react-native-render-html";
|
|
||||||
import {Linking} from "expo";
|
|
||||||
import {Avatar, Card, Chip, Paragraph, withTheme} from 'react-native-paper';
|
import {Avatar, 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/Custom/CustomHTML";
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
navigation: Object,
|
navigation: Object,
|
||||||
|
|
@ -18,10 +17,6 @@ type State = {
|
||||||
imageModalVisible: boolean,
|
imageModalVisible: boolean,
|
||||||
};
|
};
|
||||||
|
|
||||||
function openWebLink(event, link) {
|
|
||||||
Linking.openURL(link).catch((err) => console.error('Error opening link', err));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 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.
|
||||||
|
|
@ -146,12 +141,7 @@ class ClubDisplayScreen extends React.Component<Props, State> {
|
||||||
{data.description !== null ?
|
{data.description !== null ?
|
||||||
// Surround description with div to allow text styling if the description is not html
|
// Surround description with div to allow text styling if the description is not html
|
||||||
<Card.Content>
|
<Card.Content>
|
||||||
<HTML html={"<div>" + data.description + "</div>"}
|
<CustomHTML html={data.description}/>
|
||||||
tagsStyles={{
|
|
||||||
p: {color: this.colors.text,},
|
|
||||||
div: {color: this.colors.text}
|
|
||||||
}}
|
|
||||||
onLinkPress={openWebLink}/>
|
|
||||||
</Card.Content>
|
</Card.Content>
|
||||||
: <View/>}
|
: <View/>}
|
||||||
{this.getManagersRender(data.responsibles)}
|
{this.getManagersRender(data.responsibles)}
|
||||||
|
|
|
||||||
|
|
@ -24,15 +24,12 @@ class ProfileScreen extends React.Component<Props, State> {
|
||||||
dialogVisible: false,
|
dialogVisible: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
colors: Object;
|
|
||||||
|
|
||||||
data: Object;
|
data: Object;
|
||||||
|
|
||||||
flatListData: Array<Object>;
|
flatListData: Array<Object>;
|
||||||
|
|
||||||
constructor(props) {
|
constructor() {
|
||||||
super(props);
|
super();
|
||||||
this.colors = props.theme.colors;
|
|
||||||
this.flatListData = [
|
this.flatListData = [
|
||||||
{id: '0'},
|
{id: '0'},
|
||||||
{id: '1'},
|
{id: '1'},
|
||||||
|
|
@ -104,18 +101,6 @@ class ProfileScreen extends React.Component<Props, State> {
|
||||||
: i18n.t("profileScreen.noData");
|
: i18n.t("profileScreen.noData");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the color depending on the value.
|
|
||||||
*
|
|
||||||
* @param field The field to get the color for
|
|
||||||
* @return {*}
|
|
||||||
*/
|
|
||||||
getFieldColor(field: ?string) {
|
|
||||||
return this.isFieldAvailable(field)
|
|
||||||
? this.colors.text
|
|
||||||
: this.colors.textDisabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets a list item showing personal information
|
* Gets a list item showing personal information
|
||||||
*
|
*
|
||||||
|
|
@ -124,15 +109,17 @@ class ProfileScreen extends React.Component<Props, State> {
|
||||||
* @return {*}
|
* @return {*}
|
||||||
*/
|
*/
|
||||||
getPersonalListItem(field: ?string, icon: string) {
|
getPersonalListItem(field: ?string, icon: string) {
|
||||||
|
let title = this.isFieldAvailable(field) ? this.getFieldValue(field) : ':(';
|
||||||
|
let subtitle = this.isFieldAvailable(field) ? '' : this.getFieldValue(field);
|
||||||
return (
|
return (
|
||||||
<List.Item
|
<List.Item
|
||||||
title={this.getFieldValue(field)}
|
title={title}
|
||||||
|
description={subtitle}
|
||||||
left={props => <List.Icon
|
left={props => <List.Icon
|
||||||
{...props}
|
{...props}
|
||||||
icon={icon}
|
icon={icon}
|
||||||
color={this.getFieldColor(field)}
|
color={this.isFieldAvailable(field) ? undefined : this.props.theme.colors.textDisabled}
|
||||||
/>}
|
/>}
|
||||||
titleStyle={{color: this.getFieldColor(field)}}
|
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -151,7 +138,7 @@ class ProfileScreen extends React.Component<Props, State> {
|
||||||
left={(props) => <Avatar.Icon
|
left={(props) => <Avatar.Icon
|
||||||
{...props}
|
{...props}
|
||||||
icon="account"
|
icon="account"
|
||||||
color={this.colors.primary}
|
color={this.props.theme.colors.primary}
|
||||||
style={styles.icon}
|
style={styles.icon}
|
||||||
/>}
|
/>}
|
||||||
/>
|
/>
|
||||||
|
|
@ -169,7 +156,7 @@ class ProfileScreen extends React.Component<Props, State> {
|
||||||
<Button
|
<Button
|
||||||
icon="account-edit"
|
icon="account-edit"
|
||||||
mode="contained"
|
mode="contained"
|
||||||
onPress={() => openBrowser(this.data.link, this.colors.primary)}
|
onPress={() => openBrowser(this.data.link, this.props.theme.colors.primary)}
|
||||||
style={styles.editButton}>
|
style={styles.editButton}>
|
||||||
{i18n.t("profileScreen.editInformation")}
|
{i18n.t("profileScreen.editInformation")}
|
||||||
</Button>
|
</Button>
|
||||||
|
|
@ -193,7 +180,7 @@ class ProfileScreen extends React.Component<Props, State> {
|
||||||
left={(props) => <Avatar.Icon
|
left={(props) => <Avatar.Icon
|
||||||
{...props}
|
{...props}
|
||||||
icon="account-group"
|
icon="account-group"
|
||||||
color={this.colors.primary}
|
color={this.props.theme.colors.primary}
|
||||||
style={styles.icon}
|
style={styles.icon}
|
||||||
/>}
|
/>}
|
||||||
/>
|
/>
|
||||||
|
|
@ -219,7 +206,7 @@ class ProfileScreen extends React.Component<Props, State> {
|
||||||
left={(props) => <Avatar.Icon
|
left={(props) => <Avatar.Icon
|
||||||
{...props}
|
{...props}
|
||||||
icon="credit-card"
|
icon="credit-card"
|
||||||
color={this.colors.primary}
|
color={this.props.theme.colors.primary}
|
||||||
style={styles.icon}
|
style={styles.icon}
|
||||||
/>}
|
/>}
|
||||||
/>
|
/>
|
||||||
|
|
@ -243,7 +230,7 @@ class ProfileScreen extends React.Component<Props, State> {
|
||||||
title={state ? i18n.t("profileScreen.membershipPayed") : i18n.t("profileScreen.membershipNotPayed")}
|
title={state ? i18n.t("profileScreen.membershipPayed") : i18n.t("profileScreen.membershipNotPayed")}
|
||||||
left={props => <List.Icon
|
left={props => <List.Icon
|
||||||
{...props}
|
{...props}
|
||||||
color={state ? this.colors.success : this.colors.danger}
|
color={state ? this.props.theme.colors.success : this.props.theme.colors.danger}
|
||||||
icon={state ? 'check' : 'close'}
|
icon={state ? 'check' : 'close'}
|
||||||
/>}
|
/>}
|
||||||
/>
|
/>
|
||||||
|
|
@ -270,7 +257,7 @@ class ProfileScreen extends React.Component<Props, State> {
|
||||||
let icon = (props) => <List.Icon {...props} icon="chevron-right"/>;
|
let icon = (props) => <List.Icon {...props} icon="chevron-right"/>;
|
||||||
if (item.is_manager) {
|
if (item.is_manager) {
|
||||||
description = i18n.t("profileScreen.isManager");
|
description = i18n.t("profileScreen.isManager");
|
||||||
icon = (props) => <List.Icon {...props} icon="star" color={this.colors.primary}/>;
|
icon = (props) => <List.Icon {...props} icon="star" color={this.props.theme.colors.primary}/>;
|
||||||
}
|
}
|
||||||
return <List.Item
|
return <List.Item
|
||||||
title={item.name}
|
title={item.name}
|
||||||
|
|
|
||||||
|
|
@ -83,7 +83,7 @@ class HomeScreen extends React.Component<Props> {
|
||||||
if (this.props.route.params.nextScreen !== undefined && this.props.route.params.nextScreen !== null) {
|
if (this.props.route.params.nextScreen !== undefined && this.props.route.params.nextScreen !== null) {
|
||||||
this.props.navigation.navigate(this.props.route.params.nextScreen, this.props.route.params.data);
|
this.props.navigation.navigate(this.props.route.params.nextScreen, this.props.route.params.data);
|
||||||
// reset params to prevent infinite loop
|
// reset params to prevent infinite loop
|
||||||
this.props.navigation.dispatch(CommonActions.setParams({ nextScreen: null }));
|
this.props.navigation.dispatch(CommonActions.setParams({nextScreen: null}));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -137,7 +137,7 @@ class HomeScreen extends React.Component<Props> {
|
||||||
id: SECTIONS_ID[1]
|
id: SECTIONS_ID[1]
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
}
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generates the dataset associated to the dashboard to be displayed in the FlatList as a section
|
* Generates the dataset associated to the dashboard to be displayed in the FlatList as a section
|
||||||
|
|
@ -349,7 +349,7 @@ class HomeScreen extends React.Component<Props> {
|
||||||
|
|
||||||
let displayEvent = this.getDisplayEvent(futureEvents);
|
let displayEvent = this.getDisplayEvent(futureEvents);
|
||||||
const clickContainerAction = () => this.props.navigation.navigate('planning');
|
const clickContainerAction = () => this.props.navigation.navigate('planning');
|
||||||
const clickPreviewAction = () => this.props.navigation.navigate('planning-information', {data: displayEvent});
|
const clickPreviewAction = () => this.props.navigation.navigate('home-planning-information', {data: displayEvent});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<DashboardItem
|
<DashboardItem
|
||||||
|
|
@ -469,13 +469,13 @@ class HomeScreen extends React.Component<Props> {
|
||||||
const nav = this.props.navigation;
|
const nav = this.props.navigation;
|
||||||
return (
|
return (
|
||||||
<View>
|
<View>
|
||||||
<WebSectionList
|
<WebSectionList
|
||||||
createDataset={this.createDataset}
|
createDataset={this.createDataset}
|
||||||
navigation={nav}
|
navigation={nav}
|
||||||
autoRefreshTime={REFRESH_TIME}
|
autoRefreshTime={REFRESH_TIME}
|
||||||
refreshOnFocus={true}
|
refreshOnFocus={true}
|
||||||
fetchUrl={DATA_URL}
|
fetchUrl={DATA_URL}
|
||||||
renderItem={this.getRenderItem}/>
|
renderItem={this.getRenderItem}/>
|
||||||
<FAB
|
<FAB
|
||||||
style={styles.fab}
|
style={styles.fab}
|
||||||
icon="qrcode-scan"
|
icon="qrcode-scan"
|
||||||
|
|
|
||||||
|
|
@ -2,8 +2,6 @@
|
||||||
|
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import {ScrollView, View} from 'react-native';
|
import {ScrollView, View} from 'react-native';
|
||||||
import HTML from "react-native-render-html";
|
|
||||||
import {Linking} from "expo";
|
|
||||||
import {getDateOnlyString, getFormattedEventTime} from '../../utils/Planning';
|
import {getDateOnlyString, getFormattedEventTime} from '../../utils/Planning';
|
||||||
import {Card, withTheme} from 'react-native-paper';
|
import {Card, withTheme} from 'react-native-paper';
|
||||||
import DateManager from "../../managers/DateManager";
|
import DateManager from "../../managers/DateManager";
|
||||||
|
|
@ -11,6 +9,7 @@ import ImageModal from 'react-native-image-modal';
|
||||||
import BasicLoadingScreen from "../../components/Custom/BasicLoadingScreen";
|
import BasicLoadingScreen from "../../components/Custom/BasicLoadingScreen";
|
||||||
import {apiRequest} from "../../utils/WebData";
|
import {apiRequest} from "../../utils/WebData";
|
||||||
import ErrorView from "../../components/Custom/ErrorView";
|
import ErrorView from "../../components/Custom/ErrorView";
|
||||||
|
import CustomHTML from "../../components/Custom/CustomHTML";
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
navigation: Object,
|
navigation: Object,
|
||||||
|
|
@ -21,10 +20,6 @@ type State = {
|
||||||
loading: boolean
|
loading: boolean
|
||||||
};
|
};
|
||||||
|
|
||||||
function openWebLink(event, link) {
|
|
||||||
Linking.openURL(link).catch((err) => console.error('Error opening link', err));
|
|
||||||
}
|
|
||||||
|
|
||||||
const CLUB_INFO_PATH = "event/info";
|
const CLUB_INFO_PATH = "event/info";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -111,14 +106,8 @@ class PlanningDisplayScreen extends React.Component<Props, State> {
|
||||||
: <View/>}
|
: <View/>}
|
||||||
|
|
||||||
{this.displayData.description !== null ?
|
{this.displayData.description !== null ?
|
||||||
// Surround description with div to allow text styling if the description is not html
|
|
||||||
<Card.Content>
|
<Card.Content>
|
||||||
<HTML html={"<div>" + this.displayData.description + "</div>"}
|
<CustomHTML html={this.displayData.description}/>
|
||||||
tagsStyles={{
|
|
||||||
p: {color: this.colors.text,},
|
|
||||||
div: {color: this.colors.text}
|
|
||||||
}}
|
|
||||||
onLinkPress={openWebLink}/>
|
|
||||||
</Card.Content>
|
</Card.Content>
|
||||||
: <View/>}
|
: <View/>}
|
||||||
</ScrollView>
|
</ScrollView>
|
||||||
|
|
@ -131,7 +120,7 @@ class PlanningDisplayScreen extends React.Component<Props, State> {
|
||||||
else if (this.errorCode === 0)
|
else if (this.errorCode === 0)
|
||||||
return this.getContent();
|
return this.getContent();
|
||||||
else
|
else
|
||||||
return <ErrorView {...this.props} errorCode={this.errorCode} onRefresh={this.fetchData}/>;
|
return <ErrorView {...this.props} errorCode={this.errorCode} onRefresh={this.fetchData}/>;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,7 @@ const AGENDA_MONTH_SPAN = 3;
|
||||||
/**
|
/**
|
||||||
* Class defining the app's planning screen
|
* Class defining the app's planning screen
|
||||||
*/
|
*/
|
||||||
export default class PlanningScreen extends React.Component<Props, State> {
|
class PlanningScreen extends React.Component<Props, State> {
|
||||||
|
|
||||||
agendaRef: Object;
|
agendaRef: Object;
|
||||||
|
|
||||||
|
|
@ -226,10 +226,15 @@ export default class PlanningScreen extends React.Component<Props, State> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
componentDidUpdate(prevProps: Props, prevState: State, prevContext: *): * {
|
||||||
|
console.log('coucou');
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
// console.log("rendering PlanningScreen");
|
// console.log("rendering PlanningScreen");
|
||||||
return (
|
return (
|
||||||
<CustomAgenda
|
<CustomAgenda
|
||||||
|
{...this.props}
|
||||||
// the list of items that have to be displayed in agenda. If you want to render item as empty date
|
// the list of items that have to be displayed in agenda. If you want to render item as empty date
|
||||||
// the value of date key kas to be an empty array []. If there exists no value for date key it is
|
// the value of date key kas to be an empty array []. If there exists no value for date key it is
|
||||||
// considered that the date in question is not yet loaded
|
// considered that the date in question is not yet loaded
|
||||||
|
|
@ -259,3 +264,5 @@ export default class PlanningScreen extends React.Component<Props, State> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export default PlanningScreen;
|
||||||
|
|
|
||||||
|
|
@ -4,9 +4,10 @@ import * as React from 'react';
|
||||||
import {FlatList, Image, Platform, ScrollView, View} from "react-native";
|
import {FlatList, Image, Platform, ScrollView, View} from "react-native";
|
||||||
import i18n from "i18n-js";
|
import i18n from "i18n-js";
|
||||||
import CustomModal from "../../components/Custom/CustomModal";
|
import CustomModal from "../../components/Custom/CustomModal";
|
||||||
import {IconButton, RadioButton, Searchbar, Subheading, Text, Title, withTheme} from "react-native-paper";
|
import {RadioButton, Searchbar, Subheading, Text, Title, withTheme} from "react-native-paper";
|
||||||
import {stringMatchQuery} from "../../utils/Search";
|
import {stringMatchQuery} from "../../utils/Search";
|
||||||
import ProximoListItem from "../../components/Lists/ProximoListItem";
|
import ProximoListItem from "../../components/Lists/ProximoListItem";
|
||||||
|
import HeaderButton from "../../components/Custom/HeaderButton";
|
||||||
|
|
||||||
function sortPrice(a, b) {
|
function sortPrice(a, b) {
|
||||||
return a.price - b.price;
|
return a.price - b.price;
|
||||||
|
|
@ -37,6 +38,7 @@ const LIST_ITEM_HEIGHT = 84;
|
||||||
type Props = {
|
type Props = {
|
||||||
navigation: Object,
|
navigation: Object,
|
||||||
route: Object,
|
route: Object,
|
||||||
|
theme: Object,
|
||||||
}
|
}
|
||||||
|
|
||||||
type State = {
|
type State = {
|
||||||
|
|
@ -54,8 +56,6 @@ class ProximoListScreen extends React.Component<Props, State> {
|
||||||
listData: Array<Object>;
|
listData: Array<Object>;
|
||||||
shouldFocusSearchBar: boolean;
|
shouldFocusSearchBar: boolean;
|
||||||
|
|
||||||
colors: Object;
|
|
||||||
|
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
this.listData = this.props.route.params['data']['data'];
|
this.listData = this.props.route.params['data']['data'];
|
||||||
|
|
@ -65,8 +65,6 @@ class ProximoListScreen extends React.Component<Props, State> {
|
||||||
currentSortMode: 3,
|
currentSortMode: 3,
|
||||||
modalCurrentDisplayItem: null,
|
modalCurrentDisplayItem: null,
|
||||||
};
|
};
|
||||||
|
|
||||||
this.colors = props.theme.colors;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -104,14 +102,7 @@ class ProximoListScreen extends React.Component<Props, State> {
|
||||||
* @return {*}
|
* @return {*}
|
||||||
*/
|
*/
|
||||||
getSortMenuButton = () => {
|
getSortMenuButton = () => {
|
||||||
return (
|
return <HeaderButton icon="sort" onPress={this.onSortMenuPress}/>;
|
||||||
<IconButton
|
|
||||||
icon="sort"
|
|
||||||
color={this.colors.text}
|
|
||||||
size={26}
|
|
||||||
onPress={this.onSortMenuPress}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -164,11 +155,11 @@ class ProximoListScreen extends React.Component<Props, State> {
|
||||||
getStockColor(availableStock: number) {
|
getStockColor(availableStock: number) {
|
||||||
let color: string;
|
let color: string;
|
||||||
if (availableStock > 3)
|
if (availableStock > 3)
|
||||||
color = this.colors.success;
|
color = this.props.theme.colors.success;
|
||||||
else if (availableStock > 0)
|
else if (availableStock > 0)
|
||||||
color = this.colors.warning;
|
color = this.props.theme.colors.warning;
|
||||||
else
|
else
|
||||||
color = this.colors.danger;
|
color = this.props.theme.colors.danger;
|
||||||
return color;
|
return color;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue