-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Suraj Auwal
committed
Oct 27, 2023
1 parent
41a0046
commit d49f22e
Showing
9 changed files
with
16,475 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
187 changes: 187 additions & 0 deletions
187
mobile-app/screens/AppNavigator/ListingsNavigator/screens/AddScheduledListing.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,187 @@ | ||
import { KeyboardAvoidingView, Pressable, ScrollView, Text, View} from 'react-native' | ||
import {useMemo, useState} from "react"; | ||
import {Picker} from '@react-native-picker/picker' | ||
import { tailwind} from '@tailwind' | ||
import {GoBackButton} from "@screens/AppNavigator/SettingsNavigator/components/Goback"; | ||
import {NavigationProp, useNavigation} from "@react-navigation/native"; | ||
|
||
import {IconComponent} from "@components/commons/IconComponent"; | ||
|
||
import {GenericButton} from "@components/commons/buttons/GenericButton"; | ||
|
||
import {ListingCategoryI} from "@nanahq/sticky"; | ||
import {RootState, useAppDispatch, useAppSelector} from "@store/index"; | ||
import {_api} from "@api/_request"; | ||
|
||
import { showTost } from '@components/commons/Toast'; | ||
import { useToast } from 'react-native-toast-notifications'; | ||
|
||
import DateTimePicker, {DateTimePickerAndroid} from "@react-native-community/datetimepicker"; | ||
import {TextInputWithLabel} from "@components/commons/inputs/TextInputWithLabel"; | ||
import {fetchScheduled} from "@store/listings.reducer"; | ||
import * as Device from 'expo-device' | ||
import {AndroidPickerListing} from "@screens/AppNavigator/ListingsNavigator/screens/components/AndroidPicker"; | ||
|
||
export function AddScheduledListing (): JSX.Element { | ||
const navigation = useNavigation() | ||
const dispatch = useAppDispatch() | ||
|
||
const {listingsCategory} = useAppSelector((state: RootState) => state.listings) | ||
|
||
const toast = useToast() | ||
|
||
const [menuForm, setMenuForm] = useState({ | ||
availableDate: new Date() as any, | ||
listing: "", | ||
quantity: '' as any | ||
}) | ||
|
||
|
||
|
||
const showDatePickerAndriod = () => { | ||
DateTimePickerAndroid.open({ | ||
is24Hour: true, | ||
value:menuForm.availableDate, | ||
mode:'date', | ||
onChange: (_, value) => setMenuForm((prev) => ({...prev, availableDate: value})) | ||
}) | ||
} | ||
|
||
|
||
|
||
const preOrderListingsCategories = useMemo(() =>{ | ||
return listingsCategory.filter((li) => li.type === 'PRE_ORDER') | ||
.flatMap(cat => cat.listingsMenu) | ||
}, [listingsCategory]) | ||
|
||
|
||
const [loading, setLoading] = useState<boolean>(false) | ||
async function onSubmitCb (): Promise<void> { | ||
|
||
try { | ||
setLoading(true) | ||
const res = (await _api.requestData({ | ||
method: 'post', | ||
url: 'listing/scheduled', | ||
headers:{ | ||
'Content-Type': 'multipart/form-data', | ||
'Access-Control-Allow-Origin': '*' | ||
}, | ||
data: {...menuForm, availableDate: menuForm.availableDate.getTime()} | ||
})).data | ||
|
||
await dispatch(fetchScheduled()) | ||
if (res.status === 1) { | ||
showTost(toast, 'Scheduled Listing!', 'success') | ||
setTimeout(() => { | ||
void navigation.goBack() | ||
}, 3000) | ||
} | ||
} catch (error: any){ | ||
console.log({error}) | ||
showTost( toast, typeof error.message !== 'string' ? error.message[0] : error.message, 'error') | ||
|
||
} finally { | ||
setLoading(false) | ||
} | ||
|
||
|
||
} | ||
|
||
|
||
return ( | ||
<KeyboardAvoidingView style={tailwind('px-5 bg-white flex-1')}> | ||
<ScrollView showsVerticalScrollIndicator={false}> | ||
<GoBackButton onPress={() => navigation.goBack()} /> | ||
<View> | ||
<View style={tailwind('w-2/3 mt-6')}> | ||
<Text style={tailwind('font-medium text-sm text-brand-black-500')}>Menu</Text> | ||
<Text style={tailwind('font-normal text-xs text-brand-gray-700')}> | ||
Food menu you want to add a schedule. These menu are from pre-orders category | ||
</Text> | ||
</View> | ||
<Picker | ||
style={{padding: 0, margin: 0}} | ||
selectedValue={menuForm.listing} | ||
onValueChange={(item) => setMenuForm((prev) => ({...prev, listing: item}))} | ||
> | ||
<Picker.Item value="" label="Select Menu/Food Item" /> | ||
{preOrderListingsCategories.map((cat, index) => ( | ||
<Picker.Item key={index} value={cat._id} label={cat.name} /> | ||
))} | ||
</Picker> | ||
</View> | ||
<TextInputWithLabel | ||
onChangeText={(value) => setMenuForm((prev) => ({...prev, quantity: value as any}))} | ||
keyboardType='number-pad' | ||
label='Quantity' | ||
labelTestId="" | ||
containerStyle={tailwind('w-1/2')} | ||
collapsable | ||
placeholder="20" | ||
value={menuForm.quantity as any} | ||
moreInfo="Number of packs/servings you will be making of this food." | ||
/> | ||
|
||
<View style={tailwind('flex flex-row items-center w-full ')}> | ||
<View style={tailwind('w-2/3 mt-6')}> | ||
<Text style={tailwind('font-medium text-sm text-brand-black-500')}>Available Date</Text> | ||
<Text style={tailwind('font-normal text-xs text-brand-gray-700')}> | ||
Date in the future when this listing will be available | ||
</Text> | ||
</View> | ||
{Device.osName === 'Android' ? ( | ||
<AndroidPickerListing time={menuForm.availableDate} onPress={showDatePickerAndriod} /> | ||
) : ( | ||
<DateTimePicker | ||
minimumDate={new Date()} | ||
style={tailwind('w-1/3 mt-6')} | ||
value={menuForm.availableDate as any} | ||
mode='date' | ||
onChange={(_, value) => setMenuForm((prev) => ({...prev, availableDate: value as any}))} | ||
/> | ||
)} | ||
|
||
</View> | ||
<GenericButton loading={loading} onPress={() => onSubmitCb()} label='Add Listing' backgroundColor={tailwind({'bg-brand-black-500': !loading, 'bg-brand-gray-700': loading})} labelColor={tailwind('text-white')} testId="" style={tailwind('w-full my-20')} /> | ||
</ScrollView> | ||
</KeyboardAvoidingView> | ||
) | ||
} | ||
|
||
|
||
|
||
function SelectHeader (props: {navigation: NavigationProp<any>}): JSX.Element { | ||
return ( | ||
<View style={tailwind('flex flex-row w-full items-center justify-between mt-10')}> | ||
<Text style={tailwind('font-medium text-sm text-brand-black-500')}>Category</Text> | ||
<Pressable onPress={() => props.navigation.navigate("AddCategory")} style={tailwind('flex flex-row items-center')}> | ||
<Text style={tailwind('font-semibold text-xs text-brand-black-500')}>Add new category</Text> | ||
<IconComponent iconType='Feather' name='plus-circle' style={tailwind('text-brand-black-500 ml-1')} /> | ||
</Pressable> | ||
</View> | ||
) | ||
} | ||
|
||
|
||
function OptionHeader (props: {navigation: NavigationProp<any>}): JSX.Element { | ||
return ( | ||
<View style={tailwind('flex flex-row w-full items-center justify-between mt-3')}> | ||
<Text style={tailwind('text-sm text-brand-black-500')}>No options added yet?</Text> | ||
<Pressable onPress={() => props.navigation.navigate("AddOption")} style={tailwind('flex flex-row items-center')}> | ||
<Text style={tailwind('font-semibold text-xs text-brand-black-500')}>Add new option</Text> | ||
<IconComponent iconType='Feather' name='plus-circle' style={tailwind('text-brand-black-500 ml-1')} /> | ||
</Pressable> | ||
</View> | ||
) | ||
} | ||
|
||
function CategoryItem ({cat, onPress}: {cat: ListingCategoryI, onPress: () => void}): JSX.Element { | ||
return ( | ||
<Pressable onPress={onPress} style={tailwind('flex flex-col items-center w-full mb-3 py-4 px-2 border-b-0.5 border-brand-black-500')}> | ||
<View style={tailwind('flex w-full flex-row items-center justify-between')}> | ||
<Text style={tailwind('text-brand-black-500 text-sm font-medium')}>{cat.name}</Text> | ||
</View> | ||
</Pressable> | ||
) | ||
} |
84 changes: 84 additions & 0 deletions
84
mobile-app/screens/AppNavigator/ListingsNavigator/screens/ScheduledListings.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
import { Pressable, Text, View} from 'react-native' | ||
import {EmptyMenu} from "@components/Empty/Listings"; | ||
import { ScheduledListingI} from "@nanahq/sticky"; | ||
import {tailwind} from "@tailwind"; | ||
import {FlashList, ListRenderItemInfo} from "@shopify/flash-list"; | ||
import {LoaderComponent} from "@components/commons/LoaderComponent"; | ||
import {useCallback} from "react"; | ||
import {IconButton} from "@components/commons/buttons/IconButton"; | ||
import {useNavigation} from "@react-navigation/native"; | ||
import moment from "moment"; | ||
|
||
export function ScheduledListings (props: {listings: ScheduledListingI[], state: boolean}): JSX.Element { | ||
|
||
function onListingPress (listing: ScheduledListingI): void { | ||
|
||
} | ||
|
||
|
||
const renderItem = useCallback(({item}: ListRenderItemInfo<ScheduledListingI>): JSX.Element => { | ||
return <ListingCard | ||
onPress={onListingPress} | ||
listing={item} | ||
/> | ||
}, []) | ||
if (props.listings.length <= 0) { | ||
return ( | ||
<EmptyMenu | ||
type='MENU' | ||
title="Scheduled Listing" | ||
subtitle='Food and drinks that will be available in the future based on preorders' | ||
/> | ||
) | ||
} | ||
|
||
if (props.state) { | ||
return <View style={tailwind('flex h-full w-full items-center justify-center')}> | ||
<LoaderComponent style={tailwind('text-primary-500')} size='large' /> | ||
</View> | ||
|
||
} | ||
|
||
|
||
return ( | ||
<View style={tailwind('flex-1 bg-white')}> | ||
<FlashList | ||
contentContainerStyle={tailwind('py-4')} | ||
data={props.listings} | ||
renderItem={renderItem} | ||
keyExtractor={(item) => item._id} | ||
estimatedItemSize={props.listings.length} | ||
showsVerticalScrollIndicator={false} | ||
/> | ||
</View> | ||
) | ||
|
||
} | ||
|
||
export function ListingCard ({listing, onPress}: {listing:ScheduledListingI, onPress: (listing: ScheduledListingI) => void}) { | ||
const date = moment(listing.availableDate).format('ddd Do MMMM') | ||
return ( | ||
<Pressable onPress={() => onPress(listing)} style={[tailwind('flex w-full h-full px-2 mb-4 rounded-lg overflow-hidden'), { | ||
|
||
}]}> | ||
<View style={tailwind('overflow-hidden bg-white border-0.5 border-brand-black-500 rounded-lg')}> | ||
<View style={tailwind('p-4')}> | ||
<View style={tailwind('flex flex-row justify-between w-full items-center')}> | ||
<Text style={tailwind('font-semibold text-lg text-brand-black-500')}>{listing.listing.name}</Text> | ||
<IconButton iconName="more-horizontal" iconType="Feather" iconSize={24} iconStyle={tailwind('text-brand-gray-700')} /> | ||
</View> | ||
<View style={tailwind('flex flex-col w-full')}> | ||
<View style={tailwind('flex flex-row items-center')}> | ||
<Text style={tailwind('text-lg font-medium text-brand-black-500 mr-4')}>Quantity</Text> | ||
<Text style={tailwind('text-lg font-medium text-brand-black-500 font-bold')}>{listing.quantity}</Text> | ||
</View> | ||
<View style={tailwind('flex flex-row items-center')}> | ||
<Text style={tailwind('text-lg font-medium text-brand-black-500 mr-5')}>Available Date</Text> | ||
<Text style={tailwind('text-lg font-medium text-brand-black-500 font-bold')}>{date}</Text> | ||
</View> | ||
</View> | ||
</View> | ||
</View> | ||
</Pressable> | ||
) | ||
} |
22 changes: 22 additions & 0 deletions
22
mobile-app/screens/AppNavigator/ListingsNavigator/screens/components/AndroidPicker.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
import React, {memo} from "react"; | ||
import {Text, TouchableOpacity, View} from "react-native"; | ||
import moment from 'moment'; | ||
import {tailwind} from "@tailwind"; | ||
|
||
function Component (props: {time: Date, onPress: () => void}): JSX.Element { | ||
const choosenDate = moment(props.time).format('ddd Do MMM') | ||
return ( | ||
<View | ||
style={tailwind('w-1/3 ')} | ||
> | ||
<TouchableOpacity | ||
style={tailwind('flex flex-row w-full items-center bg-primary-200 p-2.5 rounded')} | ||
onPress={props.onPress} | ||
> | ||
<Text style={tailwind('text-center text-sm w-full font-medium')}>{choosenDate}</Text> | ||
</TouchableOpacity> | ||
</View> | ||
) | ||
} | ||
|
||
export const AndroidPickerListing = memo(Component) |
22 changes: 22 additions & 0 deletions
22
mobile-app/screens/AppNavigator/SettingsNavigator/components/AndroidPicker.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
import React, {memo} from "react"; | ||
import {Text, TouchableOpacity, View} from "react-native"; | ||
import moment from 'moment'; | ||
import {tailwind} from "@tailwind"; | ||
|
||
function Component (props: {time: Date, onPress: () => void}): JSX.Element { | ||
const choosenDate = moment(props.time).format('HH:mm') | ||
return ( | ||
<View | ||
style={tailwind('w-1/3 ml-3')} | ||
> | ||
<TouchableOpacity | ||
style={tailwind('flex flex-row w-full items-center bg-primary-200 p-2.5 rounded')} | ||
onPress={props.onPress} | ||
> | ||
<Text style={tailwind('text-center text-sm w-full font-medium')}>{choosenDate}</Text> | ||
</TouchableOpacity> | ||
</View> | ||
) | ||
} | ||
|
||
export const AndroidPicker = memo(Component) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
import {createAsyncThunk, createSlice, PayloadAction,} from "@reduxjs/toolkit"; | ||
import {AppActions} from "@store/reducers.actions"; | ||
import {_api} from "@api/_request"; | ||
import {DeliveryI} from "@nanahq/sticky"; | ||
|
||
export interface DeliveryState { | ||
deliveries: DeliveryI[], | ||
hasFetchedDeliveries: boolean, | ||
fetchingDeliveries: boolean | ||
} | ||
|
||
const initialState: DeliveryState = { | ||
deliveries: [], | ||
hasFetchedDeliveries: false, | ||
fetchingDeliveries: false | ||
}; | ||
|
||
export const fetchDeliveries = createAsyncThunk( | ||
AppActions.FETCH_DELIVERIES, | ||
async () => { | ||
return (await _api.requestData({ | ||
method: 'get', | ||
url: 'delivery/deliveries' | ||
})).data | ||
} | ||
) | ||
|
||
export const deliveries = createSlice({ | ||
name: "deliveries", | ||
initialState, | ||
reducers: { | ||
setHasFetchedDeliveries: (state, action: PayloadAction<boolean>) => { | ||
state.hasFetchedDeliveries = action.payload | ||
} | ||
}, | ||
extraReducers: (builder) => { | ||
builder | ||
.addCase( | ||
fetchDeliveries.fulfilled, | ||
(state, {payload: data}: PayloadAction<DeliveryI[]>) => { | ||
state.deliveries = data | ||
state.fetchingDeliveries = false | ||
state.hasFetchedDeliveries = true | ||
} | ||
) | ||
}, | ||
}); | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.