I'm building a React Native gig guide app.
Each gig is represented by a document in the firebase collection and has an associated date property.
I want to display the current day's gigs to the user. I also the user to tap a "next day's gigs" button and be shown a list of gigs for the next day, as follows:
I can get the current day's gigs without issue using the following logic:
const day = new Date().getDate();
const month = new Date().getMonth() + 1;
const year = new Date().getFullYear();
const dateToday = `${day}/${month}/${year}`;
//Filtering through gigs to return only current day's gigs
const gigsToday = gigs.filter((gig) => gig.date === dateToday);
...but how do I show the next/previous day's gigs?
Here's what I've done so far
1.) Convert the new Date()
to a UTC+13 time:
const addHours = (numOfHours, date = new Date()) => {
date.setTime(date.getTime() + numOfHours * 60 * 60 * 1000);
return date;
};
let localDate = addHours(13);
2.) Set up an onPress event that increments the state variable daysAdded
by 1:
<Pressable onPress={addDay}>
<Text style={styles.buttonOptionsText}>next day's gigs</Text>
</Pressable>
3.) Create a function that adds a day to the localDate
variable, and then set that new date to state variable date
:
const [date, setDate] = useState(dateToday);
...
const addDay = () => {
setDaysAdded(daysAdded + 1);
localDate.setDate(localDate.getDate() + daysAdded);
setDate(localDate);
};
The problem is that the initial date state is not immediately loaded, which means I can't conditionally render dates based on their date. I'm confused about something else - I have a date that I want to manipulate, so do I set this date as a variable or a piece of state?
Anyway, ideally once the user presses the "next days gigs" button, the app will conditionally render the gigs for the next day.
I should also mention that the date being returned from my Firebase Firestore is in the form "DD/MM/YYYY"
Full code is as follows:
GigMap.js
import { useState, useEffect } from "react";
import { StyleSheet, Text, View, Pressable } from "react-native";
import MapView from "react-native-maps";
import { Marker, Callout } from "react-native-maps";
import CalloutView from "./CalloutView";
import { mapStyle } from "../util/mapStyle";
import { useGigs } from "../hooks/useGigs";
const GigMap = ({ navigation }) => {
const [date, setDate] = useState(dateToday);
const gigs = useGigs()
const [daysAdded, setDaysAdded] = useState(1);
const addHours = (numOfHours, date = new Date()) => {
date.setTime(date.getTime() + numOfHours * 60 * 60 * 1000);
return date;
};
let localDate = addHours(13);
useEffect(() => {
setDate(localDate);
}, []);
const addDay = () => {
setDaysAdded(daysAdded + 1);
localDate.setDate(localDate.getDate() + daysAdded);
setDate(localDate);
};
//Generating current date
const day = new Date().getDate();
const month = new Date().getMonth() + 1;
const year = new Date().getFullYear();
const dateToday = `${day}/${month}/${year}`;
//Filtering through gigs to return only current day's gigs
const gigsToday = gigs.filter((gig) => gig.date === dateToday);
return (
<View style={styles.container}>
<Text style={styles.headerText}>Today's gigs</Text>
<MapView
initialRegion={{
latitude: -41.29416,
longitude: 174.77782,
latitudeDelta: 0.03,
longitudeDelta: 0.03,
}}
style={styles.map}
customMapStyle={mapStyle}
>
{gigsToday.map((gig, i) => (
<Marker
key={i}
coordinate={{
latitude: gig.location.latitude,
longitude: gig.location.longitude,
}}
image={require("../assets/Icon_Gold_48x48.png")}
>
<Callout
style={styles.callout}
onPress={() =>
navigation.navigate("GigDetails", {
venue: gig.venue,
date: gig.date,
gigName: gig.gigName,
time: gig.time,
})
}
>
<CalloutView
venue={gig.venue}
date={gig.date}
gigName={gig.gigName}
time={gig.time}
style={styles.calloutView}
/>
</Callout>
</Marker>
))}
</MapView>
<View style={styles.buttonOptions}>
<Pressable>
<Text style={styles.buttonOptionsText}>previous day's gigs</Text>
</Pressable>
<Pressable onPress={addDay}>
<Text style={styles.buttonOptionsText}>next day's gigs</Text>
</Pressable>
</View>
</View>
);
};
const styles = StyleSheet.create({
container: {
flexDirection: "column",
alignItems: "center",
},
map: {
height: 500,
width: 330,
margin: 10,
},
headerText: {
color: "black",
fontSize: 20,
marginTop: 5,
},
callout: {
width: 200,
height: 100,
},
buttonOptions: {
flexDirection: "row",
justifyContent: "flex-start",
},
buttonOptionsText: {
margin: 5,
},
});
export default GigMap;