Skip to content

Commit

Permalink
fix: fixes on android
Browse files Browse the repository at this point in the history
  • Loading branch information
Suraj Auwal committed Oct 27, 2023
1 parent 41a0046 commit d49f22e
Show file tree
Hide file tree
Showing 9 changed files with 16,475 additions and 2 deletions.
2 changes: 1 addition & 1 deletion app.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"description": "Reach a wider audience and sell more with Nana",
"slug": "nana-vendors-app",
"owner": "nana-app",
"version": "2.1.0",
"version": "1.1.0",
"orientation": "portrait",
"icon": "./assets/app-config/icon.png",
"scheme": "myapp",
Expand Down
Binary file added assets/app-config/splash.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
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>
)
}
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>
)
}
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)
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)
48 changes: 48 additions & 0 deletions mobile-app/store/delivery.reducer.ts
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
}
)
},
});

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "nanavendors",
"version": "2.1.0",
"version": "1.1.0",
"main": "index.js",
"scripts": {
"prepare": "husky install",
Expand Down
Loading

0 comments on commit d49f22e

Please sign in to comment.