Add container pickup notification
This commit is contained in:
parent
8167a693a2
commit
2dc735ed92
4 changed files with 124 additions and 122 deletions
|
@ -1,6 +1,6 @@
|
|||
import React, { useEffect, useState } from 'react';
|
||||
import { SafeAreaView, ScrollView, StyleSheet, Switch, TouchableOpacity, } from 'react-native';
|
||||
import { useNavigation } from '@react-navigation/native';
|
||||
import { SafeAreaView, ScrollView, StyleSheet, Switch, TouchableOpacity } from 'react-native';
|
||||
import { useNavigation, NavigationProp } from '@react-navigation/native';
|
||||
import { DateTimePickerAndroid, DateTimePickerEvent } from '@react-native-community/datetimepicker';
|
||||
import { useSelector } from 'react-redux';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
@ -16,65 +16,94 @@ import { store } from '@/src/store/store';
|
|||
import { setSession } from '@/src/store/dataStore';
|
||||
import { ThemedIcon } from '@/src/components/themed/ThemedIcon';
|
||||
|
||||
interface NotificationType {
|
||||
key: 'dayBefore' | 'sameDay' | 'pickup';
|
||||
label: string;
|
||||
defaultTime: string;
|
||||
minTime?: string;
|
||||
maxTime?: string;
|
||||
}
|
||||
|
||||
interface NotificationsState {
|
||||
[ key: string ]: {
|
||||
enabled: boolean;
|
||||
time: string;
|
||||
};
|
||||
}
|
||||
|
||||
export default function CategoryScreen() {
|
||||
const colorScheme = useColorScheme() ?? 'light';
|
||||
const navigation = useNavigation();
|
||||
const navigation = useNavigation<NavigationProp<any>>();
|
||||
const { token } = useToken();
|
||||
const { t } = useTranslation();
|
||||
const session = useSelector( (state: any) => state.data.session );
|
||||
|
||||
const [ sessionSet, setSessionSet ] = useState( false );
|
||||
|
||||
const [ isDayBeforeEnabled, setIsDayBeforeEnabled ] = useState( true );
|
||||
const [ dayBefore, setDayBefore ] = useState( '19:30' );
|
||||
const notificationTypes: NotificationType[] = [
|
||||
{
|
||||
key: 'dayBefore',
|
||||
label: t( "day-before" ),
|
||||
defaultTime: '19:30',
|
||||
minTime: '16:00',
|
||||
},
|
||||
{
|
||||
key: 'sameDay',
|
||||
label: t( "same-day" ),
|
||||
defaultTime: '08:00',
|
||||
maxTime: '09:00',
|
||||
},
|
||||
{
|
||||
key: 'pickup',
|
||||
label: t( "pickup" ),
|
||||
defaultTime: '17:30',
|
||||
minTime: '16:00',
|
||||
},
|
||||
];
|
||||
|
||||
const [ isSameDayEnabled, setIsSameDayEnabled ] = useState( false );
|
||||
const [ sameDay, setSameDay ] = useState( '08:00' );
|
||||
const [ notifications, setNotifications ] = useState<NotificationsState>(
|
||||
notificationTypes.reduce( (acc, type) => {
|
||||
acc[ type.key ] = { enabled: true, time: type.defaultTime };
|
||||
return acc;
|
||||
}, {} as NotificationsState )
|
||||
);
|
||||
|
||||
let currentEdit = '';
|
||||
let currentEdit: keyof NotificationsState = 'dayBefore';
|
||||
|
||||
// Set page title
|
||||
useEffect( () => {
|
||||
// Set page title
|
||||
navigation.setOptions( { title: ( t( "notifications" ) ) } );
|
||||
navigation.setOptions( { title: t( "notifications" ) } );
|
||||
}, [] );
|
||||
|
||||
// Set session data
|
||||
useEffect( () => {
|
||||
if (!sessionSet) {
|
||||
if (session.notifications.dayBefore === 'off') {
|
||||
setIsDayBeforeEnabled( false );
|
||||
} else {
|
||||
setIsDayBeforeEnabled( true );
|
||||
setDayBefore( session.notifications.dayBefore );
|
||||
}
|
||||
const newNotifications = { ...notifications };
|
||||
|
||||
if (session.notifications.sameDay === 'off') {
|
||||
setIsSameDayEnabled( false );
|
||||
} else {
|
||||
setIsSameDayEnabled( true );
|
||||
setSameDay( session.notifications.sameDay );
|
||||
}
|
||||
notificationTypes.forEach( (type) => {
|
||||
const sessionTime = session.notifications[ type.key ];
|
||||
if (sessionTime === 'off') {
|
||||
newNotifications[ type.key ].enabled = false;
|
||||
} else {
|
||||
newNotifications[ type.key ].enabled = true;
|
||||
newNotifications[ type.key ].time = sessionTime;
|
||||
}
|
||||
} );
|
||||
|
||||
setNotifications( newNotifications );
|
||||
setSessionSet( true );
|
||||
}
|
||||
|
||||
setSessionSet( true );
|
||||
}, [ session ] );
|
||||
|
||||
// Update session when something changes
|
||||
useEffect( () => {
|
||||
updateSession();
|
||||
}, [ isSameDayEnabled, sameDay, isDayBeforeEnabled, dayBefore ] );
|
||||
}, [ notifications ] );
|
||||
|
||||
// Open time picker
|
||||
const selectTime = (type: string) => {
|
||||
currentEdit = type;
|
||||
|
||||
let time;
|
||||
if (type === 'dayBefore') {
|
||||
time = new Date( `1970-01-01T${dayBefore}` );
|
||||
} else {
|
||||
time = new Date( `1970-01-01T${sameDay}` );
|
||||
}
|
||||
const selectTime = (typeKey: keyof NotificationsState) => {
|
||||
currentEdit = typeKey;
|
||||
const time = new Date( `1970-01-01T${notifications[ typeKey ].time}` );
|
||||
|
||||
if (time) {
|
||||
DateTimePickerAndroid.open( {
|
||||
|
@ -86,128 +115,104 @@ export default function CategoryScreen() {
|
|||
negativeButton: { label: t( "close" ) },
|
||||
} );
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Set selected time
|
||||
const onChange = (event: DateTimePickerEvent, selectedDate?: Date) => {
|
||||
if (selectedDate) {
|
||||
// Format to time string
|
||||
const hours = selectedDate.getHours().toString().padStart( 2, '0' );
|
||||
const minutes = selectedDate.getMinutes().toString().padStart( 2, '0' );
|
||||
const timeString = `${hours}:${minutes}`;
|
||||
|
||||
if (currentEdit === 'dayBefore') {
|
||||
const minDate = new Date( `1970-01-01T16:00` );
|
||||
const notification = notificationTypes.find( nt => nt.key === currentEdit )!;
|
||||
|
||||
if (notification.minTime) {
|
||||
const minDate = new Date( `1970-01-01T${notification.minTime}` );
|
||||
if (minDate > selectedDate) {
|
||||
Message.error( t( "notifications-before-16-00" ) );
|
||||
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
const minDate = new Date( `1970-01-01T09:00` );
|
||||
if (minDate < selectedDate) {
|
||||
} else if (notification.minTime) {
|
||||
const maxDate = new Date( `1970-01-01T${notification.minTime}` );
|
||||
if (maxDate < selectedDate) {
|
||||
Message.error( t( "notifications-after-09-00" ) );
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (currentEdit === 'dayBefore') {
|
||||
setDayBefore( timeString );
|
||||
} else {
|
||||
setSameDay( timeString )
|
||||
}
|
||||
|
||||
setNotifications( (prev) => ( {
|
||||
...prev,
|
||||
[ currentEdit ]: { ...prev[ currentEdit ], time: timeString }
|
||||
} ) );
|
||||
}
|
||||
};
|
||||
|
||||
const toggleDate = (type: string) => {
|
||||
if (type === 'dayBefore') {
|
||||
setIsDayBeforeEnabled( !isDayBeforeEnabled )
|
||||
} else {
|
||||
setIsSameDayEnabled( !isSameDayEnabled )
|
||||
}
|
||||
}
|
||||
// Enable/disable date
|
||||
const toggleDate = (typeKey: keyof NotificationsState) => {
|
||||
setNotifications( (prev) => ( {
|
||||
...prev,
|
||||
[ typeKey ]: { ...prev[ typeKey ], enabled: !prev[ typeKey ].enabled }
|
||||
} ) );
|
||||
};
|
||||
|
||||
// Update session data in API
|
||||
const updateSession = () => {
|
||||
if (!sessionSet) {
|
||||
return;
|
||||
}
|
||||
if (!sessionSet) return;
|
||||
|
||||
const postData = {
|
||||
token: token,
|
||||
notification_day_before: isDayBeforeEnabled ? dayBefore : 'off',
|
||||
notification_same_day: isSameDayEnabled ? sameDay : 'off',
|
||||
const postData: { token: string; [ key: string ]: string } = {
|
||||
token: token!,
|
||||
};
|
||||
|
||||
notificationTypes.forEach( (type) => {
|
||||
postData[ `notification_${convertCase( type.key )}` ] = notifications[ type.key ].enabled ? notifications[ type.key ].time : 'off';
|
||||
} );
|
||||
|
||||
Request.post( 'sessions/update', postData ).then( (response) => {
|
||||
if (response.success) {
|
||||
store.dispatch( setSession( response.session ) );
|
||||
} else {
|
||||
Message.error( t( "something-went-wrong" ) );
|
||||
}
|
||||
} )
|
||||
} );
|
||||
};
|
||||
|
||||
// Convert camel case to snake case
|
||||
const convertCase = (camelCaseString: string) => {
|
||||
return camelCaseString
|
||||
.replace( /([A-Z])/g, '_$1' ) // Insert an underscore before each uppercase letter
|
||||
.toLowerCase();
|
||||
}
|
||||
|
||||
return (
|
||||
<SafeAreaView style={{ flex: 1, backgroundColor: Colors[ colorScheme ].background }}>
|
||||
<ScrollView style={styles.container}>
|
||||
<ThemedView style={styles.listContainer}>
|
||||
<ThemedView style={styles.listItem}>
|
||||
<ThemedView style={styles.listTitle}>
|
||||
<Switch
|
||||
trackColor={{ false: '#767577', true: Colors[ colorScheme ].tint }}
|
||||
thumbColor={'#fff'}
|
||||
value={isDayBeforeEnabled}
|
||||
style={styles.listSwitch}
|
||||
onValueChange={() => toggleDate( 'dayBefore' )}
|
||||
/>
|
||||
<ThemedText type="defaultSemiBold">{t( "day-before" )}</ThemedText>
|
||||
</ThemedView>
|
||||
{notificationTypes.map( (type) => (
|
||||
<ThemedView key={type.key} style={styles.listItem}>
|
||||
<ThemedView style={styles.listTitle}>
|
||||
<Switch
|
||||
trackColor={{ false: '#767577', true: Colors[ colorScheme ].tint }}
|
||||
thumbColor={'#fff'}
|
||||
value={notifications[ type.key ].enabled}
|
||||
style={styles.listSwitch}
|
||||
onValueChange={() => toggleDate( type.key )}
|
||||
/>
|
||||
<ThemedText type="defaultSemiBold">{type.label}</ThemedText>
|
||||
</ThemedView>
|
||||
|
||||
{isDayBeforeEnabled ?
|
||||
(
|
||||
<TouchableOpacity style={styles.listEdit} onPress={() => selectTime( 'dayBefore' )}>
|
||||
<ThemedText style={styles.listEditText}>{t( "at" )} {dayBefore}</ThemedText>
|
||||
{notifications[ type.key ].enabled ? (
|
||||
<TouchableOpacity style={styles.listEdit} onPress={() => selectTime( type.key )}>
|
||||
<ThemedText style={styles.listEditText}>{t( "at" )} {notifications[ type.key ].time}</ThemedText>
|
||||
<ThemedIcon size={18} name="chevron-forward" style={styles.listEditIcon}/>
|
||||
</TouchableOpacity>
|
||||
) :
|
||||
(
|
||||
<ThemedText style={styles.listEdit}>
|
||||
<ThemedText style={styles.listEditText}>{t( "off" )}</ThemedText>
|
||||
</ThemedText>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
</ThemedView>
|
||||
|
||||
<ThemedView style={styles.listItem}>
|
||||
<ThemedView style={styles.listTitle}>
|
||||
<Switch
|
||||
trackColor={{ false: '#767577', true: Colors[ colorScheme ].tint }}
|
||||
thumbColor={'#fff'}
|
||||
value={isSameDayEnabled}
|
||||
style={styles.listSwitch}
|
||||
onValueChange={() => toggleDate( 'sameDay' )}
|
||||
/>
|
||||
<ThemedText type="defaultSemiBold">{t( "same-day" )}</ThemedText>
|
||||
</ThemedView>
|
||||
|
||||
{isSameDayEnabled ?
|
||||
(
|
||||
<TouchableOpacity style={styles.listEdit} onPress={() => selectTime( 'sameDay' )}>
|
||||
<ThemedText style={styles.listEditText}>{t( "at" )} {sameDay}</ThemedText>
|
||||
<ThemedIcon size={18} name="chevron-forward" style={styles.listEditIcon}/>
|
||||
</TouchableOpacity>
|
||||
) :
|
||||
(
|
||||
) : (
|
||||
<ThemedView style={styles.listEdit}>
|
||||
<ThemedText style={styles.listEditText}>{t( "off" )}</ThemedText>
|
||||
</ThemedView>
|
||||
)
|
||||
}
|
||||
|
||||
</ThemedView>
|
||||
)}
|
||||
</ThemedView>
|
||||
) )}
|
||||
</ThemedView>
|
||||
</ScrollView>
|
||||
</SafeAreaView>
|
||||
|
@ -218,9 +223,6 @@ const styles = StyleSheet.create( {
|
|||
container: {
|
||||
padding: 25,
|
||||
},
|
||||
htmlContainer: {
|
||||
paddingBottom: 50,
|
||||
},
|
||||
listContainer: {
|
||||
paddingBottom: 10
|
||||
},
|
||||
|
@ -236,9 +238,6 @@ const styles = StyleSheet.create( {
|
|||
borderBottomWidth: 1,
|
||||
borderBottomColor: '#f2f2f2',
|
||||
},
|
||||
listIcon: {
|
||||
marginRight: 15,
|
||||
},
|
||||
listTitle: {
|
||||
flex: 1,
|
||||
flexDirection: 'row',
|
||||
|
@ -260,4 +259,4 @@ const styles = StyleSheet.create( {
|
|||
listEditIcon: {
|
||||
marginLeft: 10,
|
||||
},
|
||||
} )
|
||||
} );
|
||||
|
|
|
@ -86,10 +86,11 @@
|
|||
}
|
||||
},
|
||||
"choose": "Choose",
|
||||
"notifications-before-16-00": "Meldingen voor 16:00 worden niet ondersteund",
|
||||
"notifications-after-09-00": "Meldingen na 09:00 worden niet ondersteund",
|
||||
"notifications-before-16-00": "Notifications before 16:00 are not supported",
|
||||
"notifications-after-09-00": "Notifications after 09:00 are not supported",
|
||||
"day-before": "A day before",
|
||||
"same-day": "At the same day",
|
||||
"pickup": "Pickup container",
|
||||
"off": "Off",
|
||||
"at": "at",
|
||||
"internet": {
|
||||
|
|
|
@ -90,6 +90,7 @@
|
|||
"notifications-after-09-00": "Meldingen na 09:00 worden niet ondersteund",
|
||||
"day-before": "Dag van te voren",
|
||||
"same-day": "Op de ophaaldag",
|
||||
"pickup": "Kliko ophalen",
|
||||
"off": "Uit",
|
||||
"at": "Om",
|
||||
"internet": {
|
||||
|
|
|
@ -23,6 +23,7 @@ const dataStore = createSlice( {
|
|||
notifications: {
|
||||
dayBefore: 'off',
|
||||
sameDay: 'off',
|
||||
pickup: 'off',
|
||||
},
|
||||
},
|
||||
reloadCalendar: true,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue