123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293 |
- import React, { useCallback, useEffect, useRef, useState } from 'react';
- import {
- View,
- Text,
- Image,
- TouchableOpacity,
- ScrollView,
- LayoutAnimation,
- findNodeHandle
- } from 'react-native';
- import { FlashList } from '@shopify/flash-list';
- import { CommonActions, useFocusEffect, useNavigation } from '@react-navigation/native';
- import { styles } from './styles';
- import { NAVIGATION_PAGES } from 'src/types';
- import { StoreType, storage } from 'src/storage';
- import { Header, Input, PageWrapper } from 'src/components';
- import { Colors } from 'src/theme';
- import SearchIcon from 'assets/icons/search.svg';
- import CalendarIcon from 'assets/icons/events/calendar-solid.svg';
- import EarthIcon from 'assets/icons/travels-section/earth.svg';
- import NomadsIcon from 'assets/icons/bottom-navigation/travellers.svg';
- import CalendarPlusIcon from 'assets/icons/events/calendar-plus.svg';
- import ShoppingCartIcon from 'assets/icons/events/shopping-cart.svg';
- import { SingleEvent, useGetCanAddEventQuery, useGetEventsListQuery } from '@api/events';
- import moment from 'moment';
- import { API_HOST } from 'src/constants';
- import { Grayscale } from 'react-native-color-matrix-image-filters';
- import { renderSpotsText } from './utils';
- import ChevronIcon from 'assets/icons/chevron-left.svg';
- const EventsScreen = () => {
- const token = (storage.get('token', StoreType.STRING) as string) ?? null;
- const { data, refetch } = useGetEventsListQuery(token, 0, true);
- const { data: pastData } = useGetEventsListQuery(token, 1, true);
- const { data: canAddEvent } = useGetCanAddEventQuery(token, true);
- const navigation = useNavigation();
- const [searchQuery, setSearchQuery] = useState('');
- const [events, setEvents] = useState<SingleEvent[]>([]);
- const [pastEvents, setPastEvents] = useState<SingleEvent[]>([]);
- const [filteredEvents, setFilteredEvents] = useState<SingleEvent[]>([]);
- const [filteredPastEvents, setFilteredPastEvents] = useState<SingleEvent[]>([]);
- const date = new Date();
- const [isExpanded, setIsExpanded] = useState(false);
- const scrollViewRef = useRef<ScrollView>(null);
- const sectionRef = useRef<View>(null);
- const toggleExpand = () => {
- LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut, () => {
- if (!isExpanded && sectionRef.current && scrollViewRef.current) {
- sectionRef.current.measureLayout(
- findNodeHandle(scrollViewRef.current)!,
- (x, y) => {
- scrollViewRef.current?.scrollTo({ y, animated: true });
- },
- () => console.warn('events measureLayout error')
- );
- }
- });
- setIsExpanded(!isExpanded);
- };
- useEffect(() => {
- if (data && data.data) {
- setEvents(data.data);
- setFilteredEvents(data.data);
- }
- }, [data]);
- useEffect(() => {
- if (pastData && pastData.data) {
- setPastEvents(pastData.data);
- setFilteredPastEvents(pastData.data);
- }
- }, [pastData]);
- useFocusEffect(
- useCallback(() => {
- refetch();
- }, [navigation])
- );
- const handleSearch = (text: string) => {
- if (text) {
- const searchData =
- events.filter((item: any) => {
- const itemData = item.name ? item.name.toLowerCase() : ''.toLowerCase();
- const textData = text.toLowerCase();
- return itemData.indexOf(textData) > -1;
- }) ?? [];
- setFilteredEvents(searchData);
- const searchPastData =
- pastEvents.filter((item: any) => {
- const itemData = item.name ? item.name.toLowerCase() : ''.toLowerCase();
- const textData = text.toLowerCase();
- return itemData.indexOf(textData) > -1;
- }) ?? [];
- setFilteredPastEvents(searchPastData);
- setSearchQuery(text);
- } else {
- setFilteredEvents(events);
- setFilteredPastEvents(pastEvents);
- setSearchQuery(text);
- }
- };
- const formatEventDate = (event: SingleEvent) => {
- if (event.date_from && event.date_to) {
- return `${moment(event.date_from, 'YYYY-MM-DD').format('DD MMM YYYY')} - ${moment(event.date_to, 'YYYY-MM-DD').format('DD MMM YYYY')}`;
- } else {
- return moment(event.date, 'YYYY-MM-DD').format('DD MMMM YYYY');
- }
- };
- const renderEventCard = ({ item }: { item: SingleEvent }) => {
- let staticImgUrl = '/static/img/events/meeting.webp';
- let badgeColor = Colors.DARK_BLUE;
- let badgeText = '';
- if (item.full) {
- badgeColor = Colors.LIGHT_GRAY;
- badgeText = 'FULL';
- } else if (item.type === 2) {
- badgeColor = Colors.ORANGE;
- badgeText = 'TOUR';
- staticImgUrl = '/static/img/events/trip.webp';
- } else if (item.type === 3) {
- badgeColor = Colors.DARK_BLUE;
- badgeText = 'CONF';
- staticImgUrl = '/static/img/events/conference.webp';
- }
- const photo = item.photo
- ? API_HOST + '/webapi/events/get-square-photo/' + item.id + '?cacheBust=' + date
- : API_HOST + staticImgUrl;
- return (
- <Grayscale amount={item.active === 0 ? 1 : 0}>
- <TouchableOpacity
- style={[
- styles.card,
- item.type === 2 || item.type === 3 || item.full
- ? { backgroundColor: Colors.FILL_LIGHT }
- : { backgroundColor: Colors.WHITE }
- ]}
- onPress={() =>
- navigation.navigate(...([NAVIGATION_PAGES.EVENT, { url: item.url }] as never))
- }
- disabled={item.active === 0}
- >
- <View style={styles.imageWrapper}>
- <Image source={{ uri: photo }} style={styles.image} resizeMode="cover" />
- {/* {item.isPaid && (
- <View style={styles.iconOverlay}>
- <ShoppingCartIcon fill={Colors.WHITE} width={12} />
- </View>
- )} */}
- {item.joined ? (
- <View style={styles.joinedOverlay}>
- <Text style={{ color: Colors.WHITE, fontSize: 12, fontFamily: 'redhat-700' }}>
- Joined
- </Text>
- </View>
- ) : null}
- </View>
- <View style={styles.info}>
- <Text style={styles.title} numberOfLines={2}>
- {item.name}
- </Text>
- <View style={[styles.row]}>
- <View style={styles.row}>
- <CalendarIcon fill={Colors.DARK_BLUE} height={14} width={14} />
- <Text style={[styles.dateAndLocation, { flex: 0 }]} numberOfLines={1}>
- {formatEventDate(item)}
- </Text>
- </View>
- </View>
- <View style={styles.row}>
- <EarthIcon fill={Colors.DARK_BLUE} height={14} width={14} />
- <Text style={styles.dateAndLocation} numberOfLines={1}>
- {item.address1}
- </Text>
- </View>
- {item.registrations_info !== 1 && (
- <View style={styles.row}>
- <NomadsIcon fill={Colors.DARK_BLUE} height={14} width={14} />
- <Text style={styles.dateAndLocation} numberOfLines={1}>
- {renderSpotsText(item)}
- </Text>
- </View>
- )}
- </View>
- {item.type !== 1 || item.full ? (
- <View
- style={[
- styles.statusBadge,
- { backgroundColor: item.active ? badgeColor : Colors.LIGHT_GRAY }
- ]}
- >
- <View style={styles.rotatedContainer}>
- <Text style={styles.statusText}>{badgeText}</Text>
- </View>
- </View>
- ) : null}
- </TouchableOpacity>
- </Grayscale>
- );
- };
- return (
- <PageWrapper>
- <Header
- label="Events"
- rightElement={
- canAddEvent?.can ? (
- <TouchableOpacity
- onPress={() => navigation.navigate(NAVIGATION_PAGES.CREATE_EVENT as never)}
- style={{ width: 30 }}
- >
- <CalendarPlusIcon fill={Colors.DARK_BLUE} />
- </TouchableOpacity>
- ) : null
- }
- />
- <ScrollView ref={scrollViewRef} nestedScrollEnabled showsVerticalScrollIndicator={false}>
- <View style={styles.searchContainer}>
- <Input
- inputMode={'search'}
- placeholder={'Search'}
- onChange={(text) => handleSearch(text)}
- value={searchQuery}
- icon={<SearchIcon fill={'#C8C8C8'} width={14} height={14} />}
- height={38}
- />
- </View>
- <FlashList
- data={filteredEvents}
- scrollEnabled={false}
- keyExtractor={(item) => item.id.toString()}
- renderItem={renderEventCard}
- estimatedItemSize={100}
- contentContainerStyle={styles.listContainer}
- showsVerticalScrollIndicator={false}
- />
- {filteredPastEvents && filteredPastEvents.length ? (
- <View ref={sectionRef} style={styles.sectionContainer}>
- <TouchableOpacity onPress={toggleExpand} style={styles.header}>
- <View style={styles.headerContainer}>
- <Text style={styles.headerText}>Past Events</Text>
- </View>
- <View style={styles.chevronContainer}>
- <ChevronIcon
- fill={Colors.DARK_BLUE}
- style={[styles.headerIcon, isExpanded ? styles.rotate : null]}
- />
- </View>
- </TouchableOpacity>
- {isExpanded ? (
- <FlashList
- data={filteredPastEvents}
- scrollEnabled={false}
- keyExtractor={(item) => item.id.toString()}
- renderItem={renderEventCard}
- estimatedItemSize={100}
- contentContainerStyle={styles.listContainer}
- showsVerticalScrollIndicator={false}
- />
- ) : null}
- </View>
- ) : null}
- </ScrollView>
- </PageWrapper>
- );
- };
- export default EventsScreen;
|