-
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.
Merge pull request #11 from ayghon/feat/shopping-cart
feat(shopping-cart): added logic to add/remove item in cart, added controls in article list
- Loading branch information
Showing
22 changed files
with
827 additions
and
506 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
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 |
---|---|---|
@@ -1,46 +1,16 @@ | ||
import React, { useEffect, useState } from 'react'; | ||
import { useIsFocused } from '@react-navigation/core'; | ||
import React from 'react'; | ||
|
||
import { AddArticleModal } from '../components/article-list/AddArticleModal'; | ||
import { AddArticle } from '../components/AddArticle'; | ||
import { ArticleList } from '../components/article-list/ArticleList'; | ||
import { OpenScannerFab } from '../components/scanner/OpenScannerFab'; | ||
import { useArticlesState } from '../context/articles.context'; | ||
import { useCodeState } from '../context/code.context'; | ||
import { Article } from '../types'; | ||
|
||
export default function Index() { | ||
const { code, setCode } = useCodeState(); | ||
const [isModalVisible, setModalVisible] = useState(false); | ||
const { articles, addArticle, editArticle } = useArticlesState(); | ||
|
||
const hideModal = () => { | ||
setCode(undefined); | ||
setModalVisible(false); | ||
}; | ||
const showModal = () => setModalVisible(true); | ||
|
||
const addNewArticle = (data: Article) => { | ||
if (articles.find((it) => it.id === data.id)) { | ||
editArticle(data.id, data); | ||
} else { | ||
addArticle(data); | ||
} | ||
}; | ||
|
||
useEffect(() => { | ||
if (code) { | ||
showModal(); | ||
} | ||
}, [code]); | ||
const isFocused = useIsFocused(); | ||
|
||
return ( | ||
<> | ||
<ArticleList /> | ||
<OpenScannerFab /> | ||
<AddArticleModal | ||
isOpen={isModalVisible} | ||
onSave={addNewArticle} | ||
onClose={hideModal} | ||
/> | ||
{isFocused && <AddArticle />} | ||
</> | ||
); | ||
} |
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,34 @@ | ||
import { FlatList, Row, Text } from 'native-base'; | ||
import React from 'react'; | ||
|
||
import { AddArticle } from '../components/AddArticle'; | ||
import { ArticleRow } from '../components/ArticleRow'; | ||
import { useArticlesState } from '../context/articles.context'; | ||
|
||
export default function ShoppingCart() { | ||
const { shoppingCart, addToCart } = useArticlesState(); | ||
|
||
const total = shoppingCart.reduce((acc, { price = 0, quantity = 0 }) => { | ||
return parseFloat((acc + quantity * price).toFixed(2)); | ||
}, 0); | ||
|
||
return ( | ||
<> | ||
<FlatList | ||
paddingX={4} | ||
paddingY={2} | ||
ListFooterComponent={ | ||
<Row marginTop={4} justifyContent="flex-end"> | ||
<Text>Total: {total} €</Text> | ||
</Row> | ||
} | ||
data={shoppingCart} | ||
renderItem={({ item: { id, label, price } }) => ( | ||
<ArticleRow id={id} label={label} price={price} /> | ||
)} | ||
keyExtractor={({ id }) => id} | ||
/> | ||
<AddArticle onAdd={addToCart} /> | ||
</> | ||
); | ||
} |
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,49 @@ | ||
import React, { FC, useEffect, useState } from 'react'; | ||
|
||
import { AddArticleModal } from './article-list/AddArticleModal'; | ||
import { OpenScannerFab } from './scanner/OpenScannerFab'; | ||
import { useArticlesState } from '../context/articles.context'; | ||
import { useCodeState } from '../context/code.context'; | ||
import { Article } from '../types'; | ||
|
||
type AddArticleProps = { | ||
onAdd?: (id: string) => void; | ||
}; | ||
|
||
export const AddArticle: FC<AddArticleProps> = ({ onAdd }) => { | ||
const { code, setCode } = useCodeState(); | ||
const [isModalVisible, setModalVisible] = useState(false); | ||
const { articles, addArticle, editArticle } = useArticlesState(); | ||
|
||
const hideModal = () => { | ||
setCode(undefined); | ||
setModalVisible(false); | ||
}; | ||
const showModal = () => setModalVisible(true); | ||
|
||
const addNewArticle = async (data: Article) => { | ||
if (articles.find((it) => it.id === data.id)) { | ||
await editArticle(data.id, data); | ||
} else { | ||
await addArticle(data); | ||
onAdd?.(data.id); | ||
} | ||
}; | ||
|
||
useEffect(() => { | ||
if (code) { | ||
showModal(); | ||
} | ||
}, [code]); | ||
|
||
return ( | ||
<> | ||
<OpenScannerFab /> | ||
<AddArticleModal | ||
isOpen={isModalVisible} | ||
onSave={addNewArticle} | ||
onClose={hideModal} | ||
/> | ||
</> | ||
); | ||
}; |
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,25 @@ | ||
import { IStackProps, Row } from 'native-base'; | ||
import React, { FC } from 'react'; | ||
|
||
import { ArticleLabelCell } from './article-list/ArticleLabelCell'; | ||
import { ArticlePriceCell } from './article-list/ArticlePriceCell'; | ||
|
||
type ArticleRowProps = IStackProps & { | ||
label: string; | ||
price: number; | ||
id: string; | ||
}; | ||
|
||
export const ArticleRow: FC<ArticleRowProps> = ({ | ||
label, | ||
price, | ||
id, | ||
...rest | ||
}) => { | ||
return ( | ||
<Row {...rest}> | ||
<ArticleLabelCell label={label} id={id} /> | ||
<ArticlePriceCell price={price} id={id} /> | ||
</Row> | ||
); | ||
}; |
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
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,18 @@ | ||
import { Flex, Text } from 'native-base'; | ||
import React, { FC } from 'react'; | ||
|
||
type ArticleLabelCellProps = { | ||
label: string; | ||
id: string; | ||
}; | ||
|
||
export const ArticleLabelCell: FC<ArticleLabelCellProps> = ({ label, id }) => { | ||
return ( | ||
<Flex direction="row" width="65%" alignItems="center"> | ||
<Text>{label}</Text> | ||
<Text fontSize={11} color="text.400" marginLeft={2}> | ||
{id} | ||
</Text> | ||
</Flex> | ||
); | ||
}; |
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
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,31 @@ | ||
import { MaterialIcons } from '@expo/vector-icons'; | ||
import { Link } from 'expo-router'; | ||
import { Icon, IconButton, Row } from 'native-base'; | ||
import React from 'react'; | ||
|
||
import { LanguageSelector } from '../LanguageSelector'; | ||
|
||
export const ArticleListHeaderRight = () => { | ||
return ( | ||
<Row space={4}> | ||
<Link href="shopping-cart" asChild> | ||
<IconButton | ||
variant="ghost" | ||
_pressed={{ | ||
backgroundColor: 'gray.100', | ||
}} | ||
padding={1} | ||
icon={ | ||
<Icon | ||
as={MaterialIcons} | ||
name="shopping-cart" | ||
size={6} | ||
color="gray.700" | ||
/> | ||
} | ||
/> | ||
</Link> | ||
<LanguageSelector /> | ||
</Row> | ||
); | ||
}; |
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,62 @@ | ||
import { MaterialIcons } from '@expo/vector-icons'; | ||
import { Icon, IconButton, Row, Text } from 'native-base'; | ||
import React, { FC } from 'react'; | ||
|
||
import { useArticlesState } from '../../context/articles.context'; | ||
|
||
type ArticlePriceCellProps = { | ||
price: number; | ||
id: string; | ||
}; | ||
|
||
export const ArticlePriceCell: FC<ArticlePriceCellProps> = ({ price, id }) => { | ||
const { addToCart, reduceQuantityFromCart, shoppingCart } = | ||
useArticlesState(); | ||
|
||
const itemInShoppingCart = shoppingCart.find((item) => item.id === id); | ||
|
||
return ( | ||
<Row space={1} width="35%" alignItems="center" justifyContent="center"> | ||
{!!itemInShoppingCart && ( | ||
<IconButton | ||
onPress={() => reduceQuantityFromCart(id)} | ||
variant="ghost" | ||
_pressed={{ | ||
backgroundColor: 'gray.100', | ||
}} | ||
icon={ | ||
<Icon | ||
size="lg" | ||
color="gray.700" | ||
name="remove-circle-outline" | ||
as={MaterialIcons} | ||
/> | ||
} | ||
/> | ||
)} | ||
<Text textAlign="center">{price} €</Text> | ||
{itemInShoppingCart && itemInShoppingCart.quantity > 0 && ( | ||
<Text fontSize="xs" color="text.400"> | ||
x{itemInShoppingCart.quantity} | ||
</Text> | ||
)} | ||
{!!itemInShoppingCart && ( | ||
<IconButton | ||
variant="ghost" | ||
onPress={() => addToCart(id)} | ||
_pressed={{ | ||
backgroundColor: 'gray.100', | ||
}} | ||
icon={ | ||
<Icon | ||
size="lg" | ||
color="gray.700" | ||
name="add-circle-outline" | ||
as={MaterialIcons} | ||
/> | ||
} | ||
/> | ||
)} | ||
</Row> | ||
); | ||
}; |
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.