forked from vergnet/application-amicale
Improved dashboard event item
This commit is contained in:
parent
9ec986574f
commit
c720600afd
5 changed files with 168 additions and 214 deletions
|
@ -1,190 +0,0 @@
|
|||
// @flow
|
||||
|
||||
import * as React from 'react';
|
||||
import {MaterialCommunityIcons} from "@expo/vector-icons";
|
||||
import {View} from "react-native";
|
||||
import ThemeManager from "../utils/ThemeManager";
|
||||
import HTML from "react-native-render-html";
|
||||
import {LinearGradient} from "expo-linear-gradient";
|
||||
import i18n from "i18n-js";
|
||||
import {Avatar, Card, Text} from 'react-native-paper';
|
||||
|
||||
type Props = {
|
||||
isAvailable: boolean,
|
||||
icon: string,
|
||||
color: string,
|
||||
title: string,
|
||||
subtitle: React.Node,
|
||||
clickAction: Function,
|
||||
isSquare: boolean,
|
||||
isSquareLeft: boolean,
|
||||
displayEvent: ?Object,
|
||||
}
|
||||
|
||||
export default class DashboardItem extends React.Component<Props> {
|
||||
static defaultProps = {
|
||||
isSquare: false,
|
||||
isSquareLeft: true,
|
||||
displayEvent: undefined,
|
||||
};
|
||||
|
||||
getIcon: Function;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this.getIcon = this.getIcon.bind(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the date string given by in the event list json to a date object
|
||||
* @param dateString
|
||||
* @return {Date}
|
||||
*/
|
||||
stringToDate(dateString: ?string): ?Date {
|
||||
let date = new Date();
|
||||
if (dateString === undefined || dateString === null)
|
||||
date = undefined;
|
||||
else if (dateString.split(' ').length > 1) {
|
||||
let timeStr = dateString.split(' ')[1];
|
||||
date.setHours(parseInt(timeStr.split(':')[0]), parseInt(timeStr.split(':')[1]), 0);
|
||||
} else
|
||||
date = undefined;
|
||||
return date;
|
||||
}
|
||||
|
||||
padStr(i: number) {
|
||||
return (i < 10) ? "0" + i : "" + i;
|
||||
}
|
||||
|
||||
getFormattedEventTime(event: Object): string {
|
||||
let formattedStr = '';
|
||||
let startDate = this.stringToDate(event['date_begin']);
|
||||
let endDate = this.stringToDate(event['date_end']);
|
||||
if (startDate !== undefined && startDate !== null && endDate !== undefined && endDate !== null)
|
||||
formattedStr = this.padStr(startDate.getHours()) + ':' + this.padStr(startDate.getMinutes()) +
|
||||
' - ' + this.padStr(endDate.getHours()) + ':' + this.padStr(endDate.getMinutes());
|
||||
else if (startDate !== undefined && startDate !== null)
|
||||
formattedStr = this.padStr(startDate.getHours()) + ':' + this.padStr(startDate.getMinutes());
|
||||
return formattedStr
|
||||
}
|
||||
|
||||
getEventPreviewContainer() {
|
||||
if (this.props.displayEvent !== undefined && this.props.displayEvent !== null) {
|
||||
const hasImage = this.props.displayEvent['logo'] !== '' && this.props.displayEvent['logo'] !== null;
|
||||
const getImage = () => <Avatar.Image
|
||||
source={{uri: this.props.displayEvent['logo']}}
|
||||
size={60}
|
||||
style={{backgroundColor: 'transparent'}}/>;
|
||||
return (
|
||||
<Card style={{marginBottom: 10}}>
|
||||
{hasImage ?
|
||||
<Card.Title
|
||||
title={this.props.displayEvent['title']}
|
||||
subtitle={this.getFormattedEventTime(this.props.displayEvent)}
|
||||
left={getImage}
|
||||
/> :
|
||||
<Card.Title
|
||||
title={this.props.displayEvent['title']}
|
||||
subtitle={this.getFormattedEventTime(this.props.displayEvent)}
|
||||
/>}
|
||||
<View>
|
||||
<Card.Content style={{
|
||||
height: this.props.displayEvent['description'].length > 70 ? 100 : 50,
|
||||
overflow: 'hidden',
|
||||
}}>
|
||||
<HTML html={"<div>" + this.props.displayEvent['description'] + "</div>"}
|
||||
tagsStyles={{
|
||||
p: {
|
||||
color: ThemeManager.getCurrentThemeVariables().text,
|
||||
},
|
||||
div: {color: ThemeManager.getCurrentThemeVariables().text},
|
||||
}}/>
|
||||
|
||||
</Card.Content>
|
||||
<LinearGradient
|
||||
colors={[
|
||||
// Fix for ios gradient: transparent color must match final color
|
||||
ThemeManager.getNightMode() ? 'rgba(42,42,42,0)' : 'rgba(255,255,255,0)',
|
||||
ThemeManager.getCurrentThemeVariables().card
|
||||
]}
|
||||
start={{x: 0, y: 0}}
|
||||
end={{x: 0, y: 0.6}}
|
||||
// end={[0, 0.6]}
|
||||
style={{
|
||||
position: 'absolute',
|
||||
width: '100%',
|
||||
height: 65,
|
||||
bottom: -5,
|
||||
}}>
|
||||
<View style={{
|
||||
marginLeft: 'auto',
|
||||
marginTop: 'auto',
|
||||
flexDirection: 'row'
|
||||
}}>
|
||||
<Text style={{
|
||||
marginTop: 'auto',
|
||||
marginBottom: 'auto',
|
||||
padding: 0,
|
||||
}}>
|
||||
{i18n.t("homeScreen.dashboard.seeMore")}
|
||||
</Text>
|
||||
<MaterialCommunityIcons
|
||||
name={'chevron-right'}
|
||||
size={26}
|
||||
color={ThemeManager.getCurrentThemeVariables().text}/>
|
||||
</View>
|
||||
</LinearGradient>
|
||||
</View>
|
||||
</Card>
|
||||
);
|
||||
} else
|
||||
return <View/>
|
||||
}
|
||||
|
||||
getIcon() {
|
||||
return (
|
||||
<Avatar.Icon
|
||||
icon={this.props.icon}
|
||||
color={this.props.isAvailable ? this.props.color : ThemeManager.getCurrentThemeVariables().textDisabled}
|
||||
size={60}
|
||||
style={{backgroundColor: 'transparent'}}/>
|
||||
);
|
||||
}
|
||||
|
||||
render() {
|
||||
// console.log("rendering DashboardItem " + this.props.title);
|
||||
let marginRight = 10;
|
||||
if (this.props.isSquare) {
|
||||
if (this.props.isSquareLeft)
|
||||
marginRight = '4%';
|
||||
else
|
||||
marginRight = 0
|
||||
}
|
||||
const color = this.props.isAvailable ?
|
||||
ThemeManager.getCurrentThemeVariables().text :
|
||||
ThemeManager.getCurrentThemeVariables().textDisabled;
|
||||
return (
|
||||
<Card
|
||||
style={{
|
||||
width: this.props.isSquare ? '48%' : 'auto',
|
||||
marginLeft: this.props.isSquare ? 0 : 10,
|
||||
marginRight: marginRight,
|
||||
marginTop: 10,
|
||||
overflow: 'hidden',
|
||||
}}
|
||||
onPress={this.props.clickAction}>
|
||||
|
||||
<Card.Title
|
||||
title={this.props.title}
|
||||
titleStyle={{color: color}}
|
||||
subtitle={this.props.subtitle}
|
||||
subtitleStyle={{color: color}}
|
||||
left={this.getIcon}
|
||||
/>
|
||||
<Card.Content>
|
||||
{this.getEventPreviewContainer()}
|
||||
</Card.Content>
|
||||
</Card>
|
||||
);
|
||||
}
|
||||
}
|
49
components/EventDashboardItem.js
Normal file
49
components/EventDashboardItem.js
Normal file
|
@ -0,0 +1,49 @@
|
|||
// @flow
|
||||
|
||||
import * as React from 'react';
|
||||
import {Avatar, Card, withTheme} from 'react-native-paper';
|
||||
|
||||
function getIcon(icon, color) {
|
||||
return (
|
||||
<Avatar.Icon
|
||||
icon={icon}
|
||||
color={color}
|
||||
size={60}
|
||||
style={{backgroundColor: 'transparent'}}/>
|
||||
);
|
||||
}
|
||||
|
||||
function EventDashBoardItem(props) {
|
||||
const {colors} = props.theme;
|
||||
const iconColor = props.isAvailable ?
|
||||
colors.planningColor :
|
||||
colors.textDisabled;
|
||||
const textColor = props.isAvailable ?
|
||||
colors.text :
|
||||
colors.textDisabled;
|
||||
return (
|
||||
<Card
|
||||
style={{
|
||||
width: 'auto',
|
||||
marginLeft: 10,
|
||||
marginRight: 10,
|
||||
marginTop: 10,
|
||||
overflow: 'hidden',
|
||||
}}
|
||||
onPress={props.clickAction}>
|
||||
|
||||
<Card.Title
|
||||
title={props.title}
|
||||
titleStyle={{color: textColor}}
|
||||
subtitle={props.subtitle}
|
||||
subtitleStyle={{color: textColor}}
|
||||
left={() => getIcon(props.icon, iconColor)}
|
||||
/>
|
||||
<Card.Content>
|
||||
{props.children}
|
||||
</Card.Content>
|
||||
</Card>
|
||||
);
|
||||
}
|
||||
|
||||
export default withTheme(EventDashBoardItem);
|
65
components/PreviewEventDashboardItem.js
Normal file
65
components/PreviewEventDashboardItem.js
Normal file
|
@ -0,0 +1,65 @@
|
|||
// @flow
|
||||
|
||||
import * as React from 'react';
|
||||
import {MaterialCommunityIcons} from "@expo/vector-icons";
|
||||
import {View} from "react-native";
|
||||
import HTML from "react-native-render-html";
|
||||
import i18n from "i18n-js";
|
||||
import {Avatar, Card, Text, withTheme, Button} from 'react-native-paper';
|
||||
import PlanningEventManager from "../utils/PlanningEventManager";
|
||||
|
||||
|
||||
function PreviewEventDashboardItem(props) {
|
||||
const {colors} = props.theme;
|
||||
|
||||
if (props.event !== undefined && props.event !== null) {
|
||||
const hasImage = props.event['logo'] !== '' && props.event['logo'] !== null;
|
||||
const getImage = () => <Avatar.Image
|
||||
source={{uri: props.event['logo']}}
|
||||
size={50}
|
||||
style={{backgroundColor: 'transparent'}}/>;
|
||||
return (
|
||||
<Card
|
||||
style={{marginBottom: 10}}
|
||||
onPress={props.clickAction}
|
||||
elevation={3}
|
||||
>
|
||||
{hasImage ?
|
||||
<Card.Title
|
||||
title={props.event['title']}
|
||||
subtitle={PlanningEventManager.getFormattedEventTime(props.event)}
|
||||
left={getImage}
|
||||
/> :
|
||||
<Card.Title
|
||||
title={props.event['title']}
|
||||
subtitle={PlanningEventManager.getFormattedEventTime(props.event)}
|
||||
/>}
|
||||
<Card.Content style={{
|
||||
height: props.event['description'].length > 70 ? 100 : 50,
|
||||
overflow: 'hidden',
|
||||
}}>
|
||||
<HTML html={"<div>" + props.event['description'] + "</div>"}
|
||||
tagsStyles={{
|
||||
p: {color: colors.text,},
|
||||
div: {color: colors.text},
|
||||
}}/>
|
||||
|
||||
</Card.Content>
|
||||
<Card.Actions style={{
|
||||
marginLeft: 'auto',
|
||||
marginTop: 'auto',
|
||||
flexDirection: 'row'
|
||||
}}>
|
||||
<Button
|
||||
icon={'chevron-right'}
|
||||
>
|
||||
{i18n.t("homeScreen.dashboard.seeMore")}
|
||||
</Button>
|
||||
</Card.Actions>
|
||||
</Card>
|
||||
);
|
||||
} else
|
||||
return <View/>
|
||||
}
|
||||
|
||||
export default withTheme(PreviewEventDashboardItem);
|
|
@ -5,12 +5,13 @@ import {TouchableOpacity, View} from 'react-native';
|
|||
import i18n from "i18n-js";
|
||||
import Autolink from 'react-native-autolink';
|
||||
import ThemeManager from "../utils/ThemeManager";
|
||||
import DashboardItem from "../components/DashboardItem";
|
||||
import DashboardItem from "../components/EventDashboardItem";
|
||||
import * as WebBrowser from 'expo-web-browser';
|
||||
import WebSectionList from "../components/WebSectionList";
|
||||
import {Avatar, Button, Card, Text} from 'react-native-paper';
|
||||
import FeedItem from "../components/FeedItem";
|
||||
import SquareDashboardItem from "../components/SquareDashboardItem";
|
||||
import PreviewEventDashboardItem from "../components/PreviewEventDashboardItem";
|
||||
// import DATA from "../dashboard_data.json";
|
||||
|
||||
|
||||
|
@ -24,8 +25,6 @@ const SECTIONS_ID = [
|
|||
|
||||
const REFRESH_TIME = 1000 * 20; // Refresh every 20 seconds
|
||||
|
||||
const CARD_BORDER_RADIUS = 10;
|
||||
|
||||
type Props = {
|
||||
navigation: Object,
|
||||
}
|
||||
|
@ -288,17 +287,8 @@ export default class HomeScreen extends React.Component<Props> {
|
|||
}
|
||||
|
||||
|
||||
clickAction(isAvailable: boolean, displayEvent: Object) {
|
||||
if (isAvailable)
|
||||
this.props.navigation.navigate('PlanningDisplayScreen', {data: displayEvent});
|
||||
else
|
||||
this.props.navigation.navigate('Planning');
|
||||
};
|
||||
|
||||
|
||||
getDashboardEventItem(content: Array<Object>) {
|
||||
let icon = 'calendar-range';
|
||||
let color = ThemeManager.getCurrentThemeVariables().planningColor;
|
||||
let title = i18n.t('homeScreen.dashboard.todayEventsTitle');
|
||||
let subtitle;
|
||||
let futureEvents = this.getFutureEvents(content);
|
||||
|
@ -319,17 +309,23 @@ export default class HomeScreen extends React.Component<Props> {
|
|||
subtitle = i18n.t('homeScreen.dashboard.todayEventsSubtitleNA');
|
||||
|
||||
let displayEvent = this.getDisplayEvent(futureEvents);
|
||||
const clickAction = this.clickAction.bind(this, isAvailable, displayEvent);
|
||||
const clickContainerAction = () => this.props.navigation.navigate('Planning');
|
||||
const clickPreviewAction = () => this.props.navigation.navigate('PlanningDisplayScreen', {data: displayEvent});;
|
||||
return (
|
||||
<DashboardItem
|
||||
{...this.props}
|
||||
subtitle={subtitle}
|
||||
color={color}
|
||||
icon={icon}
|
||||
clickAction={clickAction}
|
||||
clickAction={clickContainerAction}
|
||||
title={title}
|
||||
isAvailable={isAvailable}
|
||||
displayEvent={displayEvent}
|
||||
>
|
||||
<PreviewEventDashboardItem
|
||||
{...this.props}
|
||||
event={displayEvent}
|
||||
clickAction={clickPreviewAction}
|
||||
/>
|
||||
</DashboardItem>
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -3,9 +3,9 @@ export default class PlanningEventManager {
|
|||
static isEventBefore(event1: Object, event2: Object) {
|
||||
let date1 = new Date();
|
||||
let date2 = new Date();
|
||||
let timeArray = this.getEventStartTime(event1).split(":");
|
||||
let timeArray = PlanningEventManager.getEventStartTime(event1).split(":");
|
||||
date1.setHours(parseInt(timeArray[0]), parseInt(timeArray[1]));
|
||||
timeArray = this.getEventStartTime(event2).split(":");
|
||||
timeArray = PlanningEventManager.getEventStartTime(event2).split(":");
|
||||
date2.setHours(parseInt(timeArray[0]), parseInt(timeArray[1]));
|
||||
return date1 < date2;
|
||||
}
|
||||
|
@ -16,27 +16,61 @@ export default class PlanningEventManager {
|
|||
|
||||
static getEventStartTime(event: Object) {
|
||||
if (event !== undefined && Object.keys(event).length > 0 && event.date_begin !== null)
|
||||
return this.formatTime(event.date_begin.split(" ")[1]);
|
||||
return PlanningEventManager.formatTime(event.date_begin.split(" ")[1]);
|
||||
else
|
||||
return "";
|
||||
}
|
||||
|
||||
static getEventEndTime(event: Object) {
|
||||
if (event !== undefined && Object.keys(event).length > 0 && event.date_end !== null)
|
||||
return this.formatTime(event.date_end.split(" ")[1]);
|
||||
return PlanningEventManager.formatTime(event.date_end.split(" ")[1]);
|
||||
else
|
||||
return "";
|
||||
}
|
||||
|
||||
static getFormattedTime(event: Object) {
|
||||
if (this.getEventEndTime(event) !== "")
|
||||
return this.getEventStartTime(event) + " - " + this.getEventEndTime(event);
|
||||
if (PlanningEventManager.getEventEndTime(event) !== "")
|
||||
return PlanningEventManager.getEventStartTime(event) + " - " + PlanningEventManager.getEventEndTime(event);
|
||||
else
|
||||
return this.getEventStartTime(event);
|
||||
return PlanningEventManager.getEventStartTime(event);
|
||||
}
|
||||
|
||||
static formatTime(time: string) {
|
||||
let array = time.split(':');
|
||||
return array[0] + ':' + array[1];
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the date string given by in the event list json to a date object
|
||||
* @param dateString
|
||||
* @return {Date}
|
||||
*/
|
||||
static stringToDate(dateString: ?string): ?Date {
|
||||
let date = new Date();
|
||||
if (dateString === undefined || dateString === null)
|
||||
date = undefined;
|
||||
else if (dateString.split(' ').length > 1) {
|
||||
let timeStr = dateString.split(' ')[1];
|
||||
date.setHours(parseInt(timeStr.split(':')[0]), parseInt(timeStr.split(':')[1]), 0);
|
||||
} else
|
||||
date = undefined;
|
||||
return date;
|
||||
}
|
||||
|
||||
static padStr(i: number) {
|
||||
return (i < 10) ? "0" + i : "" + i;
|
||||
}
|
||||
|
||||
static getFormattedEventTime(event: Object): string {
|
||||
let formattedStr = '';
|
||||
let startDate = PlanningEventManager.stringToDate(event['date_begin']);
|
||||
let endDate = PlanningEventManager.stringToDate(event['date_end']);
|
||||
if (startDate !== undefined && startDate !== null && endDate !== undefined && endDate !== null)
|
||||
formattedStr = PlanningEventManager.padStr(startDate.getHours()) + ':' + PlanningEventManager.padStr(startDate.getMinutes()) +
|
||||
' - ' + PlanningEventManager.padStr(endDate.getHours()) + ':' + PlanningEventManager.padStr(endDate.getMinutes());
|
||||
else if (startDate !== undefined && startDate !== null)
|
||||
formattedStr = PlanningEventManager.padStr(startDate.getHours()) + ':' + PlanningEventManager.padStr(startDate.getMinutes());
|
||||
return formattedStr
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue