Commit d6368837 authored by Neosoulink's avatar Neosoulink
Browse files

feat: add screens

parent 4d20eba0
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -44,6 +44,10 @@ const DRAWER_ROUTES: DrawerScreenType[] = [
		name: 'DRAWER/TRANSLATION',
		component: SCREENS.APP.Translation,
	},
	{
		name: 'DRAWER/SEARCH',
		component: SCREENS.APP.Search,
	},
	{
		name: 'DRAWER/MERCHANTS_SEARCH',
		component: SCREENS.APP.MerchantsSearch,
+122 −7
Original line number Diff line number Diff line
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';
import { View, ActivityIndicator, FlatList, StyleSheet } from 'react-native';
import { Title } from 'react-native-paper';
import { useQuery } from '@apollo/client';
import PagerView from 'react-native-pager-view';

interface Props {}
// CONFIGS

const InStoreScreen: React.FC<Props> = ({}) => {
// TYPES/INTERFACES
import type {
	ProductInfoInterface,
	ProductsQueryArgsInterface,
} from '../../client/products/argumentInterfaces';

// SELECTORS
import { useAppSelector } from '../../store/hooks';
import { getUserData, getProductViewType } from '../../store/features/user';
import { getLanguage } from '../../store/features/translation';

// ACTIONS

// QUERIES
import { GEO_LOCATION_PRODUCTS_BY_PAGING } from '../../client/products/queries';

// COMPONENTS
import {
	FocusAwareStatusBar,
	CustomScreenHeader,
	ProductItem,
} from '../../components/Common';

// STYLES
import { GLOBAL_STYLE as GS } from '../../assets/ts/styles';

function InStoreScreen({}) {
	// SELECTORS
	const LANGUAGE = useAppSelector(getLanguage);
	const USER_DATA = useAppSelector(getUserData);
	const VIEW_TYPE = useAppSelector(getProductViewType);

	// DATA
	const PRODUCTS_QUERY_ARGS_INTERFACE: ProductsQueryArgsInterface = {
		geoLocation: {
			loc: {
				type: 'Point',
				coordinates: [
					USER_DATA?.geoLocation
						? USER_DATA?.geoLocation?.coordinates?.lng
						: 0,
					USER_DATA?.geoLocation
						? USER_DATA?.geoLocation?.coordinates?.lat
						: 0,
				],
			},
		},
	};

	// QUERIES
	const PRODUCTS_QUERY_RESPONSE = useQuery(GEO_LOCATION_PRODUCTS_BY_PAGING, {
		variables: {
			...PRODUCTS_QUERY_ARGS_INTERFACE,
		},
	});

	// STYLES
	const STYLES = StyleSheet.create({
		main: {},
		loaderContainer: { ...GS.centered, ...GS.w100, flex: 1 },
		productItemContainer: {
			...GS.mx1,
			...GS.mt2,
			...GS.mb1,
		},
	});

	return (
		<View style={STYLES.main}>
			<Text>InStore.screen</Text>
		<View style={{ ...GS.screen }}>
			<FocusAwareStatusBar
				translucent={true}
				backgroundColor='transparent'
				barStyle='light-content'
			/>

			<CustomScreenHeader title={LANGUAGE.IN_STORE} showBackBtn />

			{PRODUCTS_QUERY_RESPONSE.loading ? (
				<View style={STYLES.loaderContainer}>
					<ActivityIndicator color={'#FFF'} size={25} />
				</View>
			) : PRODUCTS_QUERY_RESPONSE.data?.geoLocationProductsByPaging &&
			  PRODUCTS_QUERY_RESPONSE.data?.geoLocationProductsByPaging
					.length ? (
				VIEW_TYPE === 'list' ? (
					<FlatList
						data={
							PRODUCTS_QUERY_RESPONSE.data
								?.geoLocationProductsByPaging
						}
						renderItem={({ item, index }) => (
							<View style={STYLES.productItemContainer}>
								<ProductItem
									type={VIEW_TYPE}
									data={{ ...item, id: index }}
								/>
							</View>
						)}
						keyExtractor={(_item, _index) => _index.toString()}
						style={{ ...GS.h100 }}
					/>
				) : (
					<PagerView style={{ ...GS.screen }}>
						{PRODUCTS_QUERY_RESPONSE.data?.geoLocationProductsByPaging?.map(
							(item: ProductInfoInterface, index: number) => (
								<View key={index}>
									<ProductItem
										key={index}
										type={VIEW_TYPE}
										data={{ ...item }}
									/>
								</View>
							),
						)}
					</PagerView>
				)
			) : (
				<View style={{ ...GS.screen, ...GS.centered }}>
					<Title>Nothing to buy for now.</Title>
				</View>
			)}
		</View>
	);
};
}

export default InStoreScreen;
+229 −0
Original line number Diff line number Diff line
import React from 'react';
import { View, ActivityIndicator, StyleSheet, ScrollView } from 'react-native';
import { Button, TextInput, Title, Text } from 'react-native-paper';
import { useLazyQuery } from '@apollo/client';
// tslint:disable-next-line: no-implicit-dependencies no-submodule-imports
import MaterialIcon from '@expo/vector-icons/MaterialCommunityIcons';
import { debounce } from 'lodash';

// TYPES/INTERFACES
import {
	QueryGetMerchantsByNameArgsInterface,
	MerchantsSearchedInterface,
} from '../../client/merchants/argumentInterfaces';

// HELPERS
import { isEmpty } from '../../helpers/utils';

// STORE
import { useAppSelector } from '../../store/hooks';
import { getUserData } from '../../store/features/user';
import { getLanguage } from '../../store/features/translation';

// QUERIES
import { GET_MERCHANTS_QUERY } from '../../client/merchants/queries';

// COMPONENTS
import {
	FocusAwareStatusBar,
	CustomScreenHeader,
	TouchableCard,
} from '../../components/Common';

// STYLES
import {
	GLOBAL_STYLE as GS,
	CONSTANT_COLOR as CC,
	CONSTANT_SIZE as CS,
} from '../../assets/ts/styles';

function SearchScreen({}) {
	// SELECTORS
	const LANGUAGE = useAppSelector(getLanguage);
	const USER_DATA = useAppSelector(getUserData);

	// STATES
	const [searchedValue, setSearchedValue] = React.useState<string>('');
	const [dataLoading, setDataLoading] = React.useState<boolean>(false);

	// QUERIES
	const SEARCH_QUERY = useLazyQuery(GET_MERCHANTS_QUERY);

	const STYLES = StyleSheet.create({
		loaderContainer: { ...GS.centered, ...GS.w100, flex: 1 },
		searchContainer: {
			...GS.px2,
			...GS.row,
			...GS.centered,
			...GS.pt2,
			height: 90,
			backgroundColor: CC.dark,
		},
		containerSearchInput: { ...GS.flex1, ...GS.mr2, height: 57 },
		searchInput: {
			...GS.bgLight,
			...GS.flex1,
			marginTop: -6,
			color: CC.dark,
			fontSize: CS.FONT_SIZE - 1,
		},
		scanBtn: { ...GS.p0, ...GS.my0, ...GS.justifyCenter, height: 57 },
		searchedText: { ...GS.FF_NunitoBold, ...GS.txtUpper },
	});

	// FUNCTIONS
	const debouncedFetchData = React.useMemo(
		() =>
			debounce((text: string) => {
				const MERCHANT_SEARCH_QUERY_ARGS: QueryGetMerchantsByNameArgsInterface =
					{
						searchName: text,
						...(isEmpty(text)
							? {
									geoLocation: {
										city: USER_DATA?.geoLocation.city,
										countryId:
											USER_DATA?.geoLocation?.countryId,
										countryName:
											USER_DATA?.geoLocation?.countryName,
										streetAddress:
											USER_DATA?.geoLocation
												?.streetAddress,
										postcode:
											USER_DATA?.geoLocation?.postcode,
										house: USER_DATA?.geoLocation?.house,
										loc: {
											type:
												USER_DATA?.geoLocation
													?.coordinates?.__typename ||
												'',
											coordinates: [
												USER_DATA?.geoLocation
													?.coordinates?.lng || 0,
												USER_DATA?.geoLocation
													?.coordinates?.lat || 0,
											],
										},
									},
							  }
							: {}),
					};
				setDataLoading(false);
				SEARCH_QUERY[0]({
					variables: MERCHANT_SEARCH_QUERY_ARGS,
				});
			}, 500),
		// eslint-disable-next-line react-hooks/exhaustive-deps
		[],
	);

	// EFFECTS
	React.useEffect(() => {
		debouncedFetchData(searchedValue);

		return () => debouncedFetchData.cancel();
		// eslint-disable-next-line react-hooks/exhaustive-deps
	}, [searchedValue]);

	return (
		<View style={{ ...GS.screen }}>
			<FocusAwareStatusBar
				translucent={true}
				backgroundColor='transparent'
				barStyle='light-content'
			/>

			<CustomScreenHeader
				title={LANGUAGE.PRODUCTS_VIEW.TITLE}
				showBackBtn
			/>

			<View style={STYLES.searchContainer}>
				<View style={STYLES.containerSearchInput}>
					<TextInput
						value={searchedValue}
						placeholder={LANGUAGE.MERCHANTS_VIEW.NAME}
						style={STYLES.searchInput}
						theme={{
							colors: { text: CC.dark },
							roundness: CS.SPACE,
						}}
						placeholderTextColor={CC.gray}
						left={
							<TextInput.Icon
								name='search'
								color={CC.dark}
								size={18}
								style={GS.mt1}
							/>
						}
						onChangeText={(text) => {
							setDataLoading(true);
							setSearchedValue(text);
						}}
						mode='outlined'
					/>
				</View>

				<Button
					style={STYLES.scanBtn}
					theme={{ roundness: CS.SPACE }}
					uppercase={false}
					mode='contained'>
					<MaterialIcon
						name='qrcode-scan'
						color={CC.light}
						size={16}
					/>{' '}
					{LANGUAGE.SCAN}
				</Button>
			</View>

			<View style={{ ...GS.centered, ...GS.pt3, ...GS.pb4 }}>
				<Text style={STYLES.searchedText}>
					{!isEmpty(searchedValue)
						? LANGUAGE.MERCHANTS_VIEW.WITH_NAME +
						  ' "' +
						  searchedValue +
						  '"'
						: LANGUAGE.MERCHANTS_VIEW.CLOSE_TO_YOU}
				</Text>
			</View>

			{SEARCH_QUERY[1].loading || dataLoading ? (
				<View style={STYLES.loaderContainer}>
					<ActivityIndicator color={CC.white} size={25} />
				</View>
			) : SEARCH_QUERY[1]?.data?.getMerchantsBuyName?.length ? (
				<ScrollView
					style={{ ...GS.screen }}
					contentContainerStyle={{ ...GS.px2 }}>
					{(SEARCH_QUERY[1]?.data
						? (SEARCH_QUERY[1]?.data
								?.getMerchantsBuyName as MerchantsSearchedInterface[])
						: []
					).map((_item, _index) => (
						<TouchableCard
							key={_index}
							img={_item.logo}
							title={_item.name}
							titleStyle={{ color: CC.primary }}
							indicatorIconProps={{ name: 'chevron-right' }}
							height={65}
							style={GS.mb2}
							onPress={() => {}}
						/>
					))}
				</ScrollView>
			) : (
				<ScrollView
					style={{ ...GS.screen }}
					contentContainerStyle={{ ...GS.screen, ...GS.centered }}>
					<Title>{LANGUAGE.NOT_FOUND}</Title>
				</ScrollView>
			)}
		</View>
	);
}

export default SearchScreen;
+2 −0
Original line number Diff line number Diff line
@@ -11,6 +11,7 @@ import HomeScreen from './app/Home.screen';
import OrderHistoryScreen from './app/OrderHistory.screen';
import AccountScreen from './app/Account.screen';
import TranslationScreen from './app/Translation.screen';
import SearchScreen from './app/Search.screen';
import MerchantsSearchScreen from './app/MerchantsSearch.screen';
import InStoreScreen from './app/InStore.screen';

@@ -25,6 +26,7 @@ const SCREENS = {
		OrderHistory: OrderHistoryScreen,
		Account: AccountScreen,
		Translation: TranslationScreen,
		Search: SearchScreen,
		MerchantsSearch: MerchantsSearchScreen,
		InStore: InStoreScreen,
	},