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 i18n from "i18n-js";
|
||||||
import Autolink from 'react-native-autolink';
|
import Autolink from 'react-native-autolink';
|
||||||
import ThemeManager from "../utils/ThemeManager";
|
import ThemeManager from "../utils/ThemeManager";
|
||||||
import DashboardItem from "../components/DashboardItem";
|
import DashboardItem from "../components/EventDashboardItem";
|
||||||
import * as WebBrowser from 'expo-web-browser';
|
import * as WebBrowser from 'expo-web-browser';
|
||||||
import WebSectionList from "../components/WebSectionList";
|
import WebSectionList from "../components/WebSectionList";
|
||||||
import {Avatar, Button, Card, Text} from 'react-native-paper';
|
import {Avatar, Button, Card, Text} from 'react-native-paper';
|
||||||
import FeedItem from "../components/FeedItem";
|
import FeedItem from "../components/FeedItem";
|
||||||
import SquareDashboardItem from "../components/SquareDashboardItem";
|
import SquareDashboardItem from "../components/SquareDashboardItem";
|
||||||
|
import PreviewEventDashboardItem from "../components/PreviewEventDashboardItem";
|
||||||
// import DATA from "../dashboard_data.json";
|
// import DATA from "../dashboard_data.json";
|
||||||
|
|
||||||
|
|
||||||
|
@ -24,8 +25,6 @@ const SECTIONS_ID = [
|
||||||
|
|
||||||
const REFRESH_TIME = 1000 * 20; // Refresh every 20 seconds
|
const REFRESH_TIME = 1000 * 20; // Refresh every 20 seconds
|
||||||
|
|
||||||
const CARD_BORDER_RADIUS = 10;
|
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
navigation: Object,
|
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>) {
|
getDashboardEventItem(content: Array<Object>) {
|
||||||
let icon = 'calendar-range';
|
let icon = 'calendar-range';
|
||||||
let color = ThemeManager.getCurrentThemeVariables().planningColor;
|
|
||||||
let title = i18n.t('homeScreen.dashboard.todayEventsTitle');
|
let title = i18n.t('homeScreen.dashboard.todayEventsTitle');
|
||||||
let subtitle;
|
let subtitle;
|
||||||
let futureEvents = this.getFutureEvents(content);
|
let futureEvents = this.getFutureEvents(content);
|
||||||
|
@ -319,17 +309,23 @@ export default class HomeScreen extends React.Component<Props> {
|
||||||
subtitle = i18n.t('homeScreen.dashboard.todayEventsSubtitleNA');
|
subtitle = i18n.t('homeScreen.dashboard.todayEventsSubtitleNA');
|
||||||
|
|
||||||
let displayEvent = this.getDisplayEvent(futureEvents);
|
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 (
|
return (
|
||||||
<DashboardItem
|
<DashboardItem
|
||||||
|
{...this.props}
|
||||||
subtitle={subtitle}
|
subtitle={subtitle}
|
||||||
color={color}
|
|
||||||
icon={icon}
|
icon={icon}
|
||||||
clickAction={clickAction}
|
clickAction={clickContainerAction}
|
||||||
title={title}
|
title={title}
|
||||||
isAvailable={isAvailable}
|
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) {
|
static isEventBefore(event1: Object, event2: Object) {
|
||||||
let date1 = new Date();
|
let date1 = new Date();
|
||||||
let date2 = 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]));
|
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]));
|
date2.setHours(parseInt(timeArray[0]), parseInt(timeArray[1]));
|
||||||
return date1 < date2;
|
return date1 < date2;
|
||||||
}
|
}
|
||||||
|
@ -16,27 +16,61 @@ export default class PlanningEventManager {
|
||||||
|
|
||||||
static getEventStartTime(event: Object) {
|
static getEventStartTime(event: Object) {
|
||||||
if (event !== undefined && Object.keys(event).length > 0 && event.date_begin !== null)
|
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
|
else
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
static getEventEndTime(event: Object) {
|
static getEventEndTime(event: Object) {
|
||||||
if (event !== undefined && Object.keys(event).length > 0 && event.date_end !== null)
|
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
|
else
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
static getFormattedTime(event: Object) {
|
static getFormattedTime(event: Object) {
|
||||||
if (this.getEventEndTime(event) !== "")
|
if (PlanningEventManager.getEventEndTime(event) !== "")
|
||||||
return this.getEventStartTime(event) + " - " + this.getEventEndTime(event);
|
return PlanningEventManager.getEventStartTime(event) + " - " + PlanningEventManager.getEventEndTime(event);
|
||||||
else
|
else
|
||||||
return this.getEventStartTime(event);
|
return PlanningEventManager.getEventStartTime(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
static formatTime(time: string) {
|
static formatTime(time: string) {
|
||||||
let array = time.split(':');
|
let array = time.split(':');
|
||||||
return array[0] + ':' + array[1];
|
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