Skip to content
This repository has been archived by the owner on Dec 9, 2021. It is now read-only.

Implement calendar filtering by event status #228

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
71 changes: 71 additions & 0 deletions app/ui/components/floatingActionButton/FloatingActionButton.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import React from 'react';
import { FloatingAction } from 'react-native-floating-action';
import Icon from 'react-native-vector-icons/MaterialIcons';
import PropTypes from 'prop-types';
import { Text, View } from 'react-native';
import Colors from '../../style/Colors';
import styles from './style/FloatingActionButton';

const renderText = (text) => (
<View style={styles.floatingActionButtonItemTextWrapper}>
<Text style={styles.floatingActionButtonItemText}>{text}</Text>
</View>
);

const renderIcon = (iconName) => {
if (iconName) {
return (
<View style={styles.floatingActionButtonItemIcon}>
<Icon name={iconName} size={26} color={Colors.white} />
</View>
);
}
return null;
};

const renderItem = (item) => (
<View key='item' style={styles.floatingActionButtonItem}>
{renderText(item.text)}
{renderIcon(item.iconName)}
</View>
);

const FloatingActionButton = (props) => {
const actions = props.actions.map((action, index) => ({
text: action.text,
icon: <Icon name={action.iconName} size={26} color={Colors.white} />,
name: index.toString(),
color: Colors.magenta,
buttonSize: 46,
textColor: Colors.white,
textBackground: Colors.magenta,
render: () => renderItem(action),
}));

const onPress = (index) => {
props.actions[index].onPress();
};

return (
<FloatingAction
color={Colors.magenta}
showBackground={false}
actions={actions}
onPressItem={onPress}
floatingIcon={<Icon name={props.iconName} size={32} color={Colors.white} />}
/>
);
};

FloatingActionButton.propTypes = {
iconName: PropTypes.string.isRequired,
actions: PropTypes.arrayOf(
PropTypes.shape({
iconName: PropTypes.string,
text: PropTypes.string,
onPress: PropTypes.func.isRequired,
})
).isRequired,
};

export default FloatingActionButton;
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import Colors from '../../../style/Colors';
import StyleSheet from '../../../style/StyleSheet';

const styles = StyleSheet.create({
floatingActionButtonItem: {
flexDirection: 'row',
alignItems: 'center',
},
floatingActionButtonItemIcon: {
backgroundColor: Colors.magenta,
width: 46,
height: 46,
marginLeft: 14,
borderRadius: 23,
justifyContent: 'center',
alignItems: 'center',
elevation: 5,
},
floatingActionButtonItemTextWrapper: {
backgroundColor: Colors.magenta,
paddingHorizontal: 10,
elevation: 5,
borderRadius: 6,
height: 28,
flexDirection: 'row',
alignItems: 'center',
},
floatingActionButtonItemText: {
color: Colors.white,
fontSize: 16,
},
});

export default styles;
34 changes: 11 additions & 23 deletions app/ui/screens/admin/AdminScreen.js
Original file line number Diff line number Diff line change
@@ -1,31 +1,28 @@
import React, { Component } from 'react';
import {
FlatList,
RefreshControl,
Switch,
Text,
TouchableHighlight,
View,
} from 'react-native';
import { FlatList, RefreshControl, Switch, Text, View } from 'react-native';
import PropTypes from 'prop-types';
import Icon from 'react-native-vector-icons/MaterialIcons';
import Snackbar from 'react-native-snackbar';
import unorm from 'unorm';

import styles from './style/AdminScreen';
import Colors from '../../style/Colors';

import SearchHeader from '../../components/searchHeader/SearchHeaderConnector';
import Button from '../../components/button/Button';
import FloatingActionButton from '../../components/floatingActionButton/FloatingActionButton';

class AdminScreen extends Component {
actions = this.props.filterTypes.map((filterType) => ({
text: filterType.label,
onPress: () => this.updateFilter(filterType.checkItem),
}));

constructor(props) {
super(props);

this.state = {
items: {},
searchKey: '',
currentFilter: 0,
currentFilter: props.filterTypes[0].checkItem,
};

for (let i = 0; i < this.props.items.length; i += 1) {
Expand Down Expand Up @@ -76,12 +73,11 @@ class AdminScreen extends Component {
};

applyFilter = (keys) => {
const { filterTypes } = this.props;
const { currentFilter } = this.state;

return keys
.filter(this.containsSearchKey)
.filter((pk) => filterTypes[currentFilter].checkItem(this.state.items[pk]));
.filter((pk) => currentFilter(this.state.items[pk]));
};

cleanSearchTerm = (term) =>
Expand All @@ -104,14 +100,10 @@ class AdminScreen extends Component {
return 0;
};

updateFilter = () => {
updateFilter = (newFilter) => {
const { currentFilter } = this.state;
const { filterTypes } = this.props;

const newFilter = (currentFilter + 1) % filterTypes.length;

if (newFilter !== currentFilter) {
Snackbar.show({ text: filterTypes[newFilter].label });
this.setState({ currentFilter: newFilter });
}
};
Expand Down Expand Up @@ -183,11 +175,7 @@ class AdminScreen extends Component {
);

const filterButton = this.props.filterTypes.length > 1 && (
<TouchableHighlight onPress={this.updateFilter} style={styles.filterButton}>
<View style={styles.filterButtonWrapper}>
<Icon name='filter-list' size={32} color={Colors.white} />
</View>
</TouchableHighlight>
<FloatingActionButton iconName='filter-list' actions={this.actions} />
);

if (keys.length === 0) {
Expand Down
23 changes: 0 additions & 23 deletions app/ui/screens/admin/style/AdminScreen.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,29 +63,6 @@ const styles = StyleSheet.create({
selected: {
backgroundColor: Colors.magenta,
},
filterButton: {
position: 'absolute',
bottom: 16,
right: 16,
borderRadius: 28,
overflow: 'hidden',
backgroundColor: Colors.grey,
android: {
elevation: 4,
},
ios: {
borderColor: Colors.lightGray,
borderStyle: 'solid',
borderWidth: 0.5,
},
},
filterButtonWrapper: {
width: 56,
height: 56,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: Colors.magenta,
},
noResultsMessage: {
fontSize: 18,
padding: 16,
Expand Down
51 changes: 50 additions & 1 deletion app/ui/screens/events/CalendarScreen.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,13 @@ import ErrorScreen from '../../components/errorScreen/ErrorScreen';
import styles from './style/CalendarScreen';
import SearchHeader from '../../components/searchHeader/SearchHeaderConnector';
import DismissKeyboardView from '../../components/dismissKeyboardView/DismissKeyboardView';
import FloatingActionButton from '../../components/floatingActionButton/FloatingActionButton';

const filters = {
all: () => true,
registered: (item) => item.registered,
open: (item) => item.registration_allowed,
};

/* eslint no-param-reassign: ["error", { "props": false }] */
const addEventToSection = (sections, date, event) => {
Expand Down Expand Up @@ -119,6 +126,31 @@ const renderItem = (item) => {
};

class CalendarScreen extends Component {
actions = [
{
text: 'All',
iconName: 'reorder',
onPress: () => this.updateFilter(filters.all),
},
{
text: 'Your registrations',
iconName: 'account-circle',
onPress: () => this.updateFilter(filters.registered),
},
{
text: 'Open registrations',
iconName: 'event-available',
onPress: () => this.updateFilter(filters.open),
},
];

constructor(props) {
super(props);
this.state = {
activeFilter: filters.all,
};
}

componentDidMount() {
const { keywords } = this.props;
this.props.events(keywords);
Expand All @@ -136,7 +168,22 @@ class CalendarScreen extends Component {
}, 500);
};

filteredEvents = () => {
const { activeFilter } = this.state;
const { eventList } = this.props;

return eventList.filter(activeFilter);
};

updateFilter = (filter) => {
this.setState({
activeFilter: filter,
});
};

render() {
const items = this.filteredEvents();

const header = (
<SearchHeader
title='Calendar'
Expand All @@ -153,7 +200,7 @@ class CalendarScreen extends Component {
renderSectionHeader={(itemHeader) => (
<Text style={styles.sectionHeader}>{itemHeader.section.key}</Text>
)}
sections={eventListToSections(this.props.eventList)}
sections={eventListToSections(items)}
keyExtractor={(item) => item.dayNumber}
stickySectionHeadersEnabled
onRefresh={this.handleRefresh}
Expand Down Expand Up @@ -199,6 +246,7 @@ class CalendarScreen extends Component {
<DismissKeyboardView contentStyle={styles.keyboardView}>
{content}
</DismissKeyboardView>
<FloatingActionButton iconName='filter-list' actions={this.actions} />
</View>
);
}
Expand All @@ -217,6 +265,7 @@ CalendarScreen.propTypes = {
start: PropTypes.string,
end: PropTypes.string,
location: PropTypes.string,
registration_allowed: PropTypes.bool.isRequired,
price: PropTypes.string,
registered: PropTypes.bool,
pizza: PropTypes.bool,
Expand Down
6 changes: 3 additions & 3 deletions app/ui/screens/events/EventAdminScreen.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,15 +50,15 @@ class EventAdminScreen extends Component {

const filterTypes = [
{
label: 'Disabled filter',
label: 'Show all',
checkItem: () => true,
},
{
label: 'Filtering on payment',
label: 'Hide paid',
checkItem: (item) => item.select.value === PAYMENT_TYPES.NONE,
},
{
label: 'Filtering on presence',
label: 'Hide present',
checkItem: (item) => !item.checkbox,
},
];
Expand Down
4 changes: 2 additions & 2 deletions app/ui/screens/pizza/PizzaAdminScreen.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,11 @@ class PizzaAdminScreen extends Component {

const filterTypes = [
{
label: 'Disabled filter',
label: 'Show all',
checkItem: () => true,
},
{
label: 'Filtering on payment',
label: 'Hide paid',
checkItem: (item) => item.select.value === PAYMENT_TYPES.NONE,
},
];
Expand Down
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
"<rootDir>/__tests__/setup.js"
],
"transformIgnorePatterns": [
"node_modules/(?!(react-native|@react-native-community|react-navigation|react-navigation-drawer|react-navigation-stack|@sentry|react-native-gesture-handler|react-native-vector-icons|react-native-linear-gradient|@react-native-firebase|react-native-image-crop-picker|react-native-reanimated|react-native-iphone-x-helper|react-native-render-html|react-native-webview|react-native-share|react-native-image-zoom-viewer|react-native-image-pan-zoom|react-native-add-calendar-event)/)"
"node_modules/(?!(react-native|@react-native-community|react-navigation|react-navigation-drawer|react-navigation-stack|@sentry|react-native-gesture-handler|react-native-vector-icons|react-native-linear-gradient|@react-native-firebase|react-native-image-crop-picker|react-native-reanimated|react-native-iphone-x-helper|react-native-render-html|react-native-webview|react-native-share|react-native-image-zoom-viewer|react-native-image-pan-zoom|react-native-add-calendar-event|react-native-floating-action)/)"
]
},
"prettier": {
Expand All @@ -67,6 +67,7 @@
"react-native-cli": "^2.0.1",
"react-native-device-info": "^7.0.2",
"react-native-dotenv": "^2.4.2",
"react-native-floating-action": "^1.21.0",
"react-native-fs": "^2.16.6",
"react-native-gesture-handler": "^1.8.0",
"react-native-image-crop-picker": "^0.35.1",
Expand All @@ -75,8 +76,8 @@
"react-native-reanimated": "^1.13.1",
"react-native-render-html": "^4.2.4",
"react-native-safe-area-context": "^3.1.8",
"react-native-share": "^4.0.4",
"react-native-screens": "^2.12.0",
"react-native-share": "^4.0.4",
"react-native-snackbar": "^2.2.3",
"react-native-vector-icons": "^7.1.0",
"react-native-webview": "^10.10.0",
Expand Down
5 changes: 5 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -7467,6 +7467,11 @@ react-native-dotenv@^2.4.2:
dependencies:
dotenv "^8.0.0"

react-native-floating-action@^1.21.0:
version "1.21.0"
resolved "https://registry.yarnpkg.com/react-native-floating-action/-/react-native-floating-action-1.21.0.tgz#cb1e8349fec5b9aed06c8053c07372822c64b22f"
integrity sha512-ozd/iaJunrEYc4eGUWkP+4UI8yoIL0nQsToI3hnJRste/3LPhBkyu0eG3RTjc6aFY+q++JpRmgO469Ck8jJOwg==

react-native-fs@^2.16.6:
version "2.16.6"
resolved "https://registry.yarnpkg.com/react-native-fs/-/react-native-fs-2.16.6.tgz#2901789a43210a35a0ef0a098019bbef3af395fd"
Expand Down