Skip to content

Commit

Permalink
JSAEM2-11 feat: apply filter to transaction view (#16)
Browse files Browse the repository at this point in the history
* JSAEM2-11 feat: apply filter to transaction view

* JSAEM2-11 apply requested changes

* JSAEM 2-11 fixed: lint issue

* JSAEM 2-11 fixed: requested changes from QA
  • Loading branch information
MichaelCTH authored and ikarasz committed Dec 24, 2019
1 parent c155679 commit 15b0a8f
Show file tree
Hide file tree
Showing 5 changed files with 95 additions and 39 deletions.
41 changes: 26 additions & 15 deletions src/Common/LargeBtn.jsx
Original file line number Diff line number Diff line change
@@ -1,29 +1,38 @@
import React from 'react';
import { View, Text } from 'react-native';
import { View, Text, TouchableOpacity } from 'react-native';
import { LinearGradient } from 'expo-linear-gradient';
import PropTypes from 'prop-types';
import styles from './themeStyle';
import themeColor from './Color';

export default function LargeButton({
subtitle, title, note, bgColor, btnWidth,
subtitle, title, note, bgColor, btnWidth, pressHandler, isShadowVisible,
}) {
const btnStyle = `${bgColor}LargeBtn`;

return (
<View style={[styles[btnStyle], { width: btnWidth }]}>
<LinearGradient
colors={themeColor.gradientColor[bgColor]}
start={[0.1, 0.9]}
end={[0.9, 0.1]}
style={{ borderRadius: 10, padding: 20 }}
>
<Text style={styles.largeBtnFont}>{subtitle}</Text>
<Text style={styles.largeBtnHeader}>
{title}
</Text>
<Text style={styles.largeBtnFont}>{note}</Text>
</LinearGradient>
<View style={[
styles[btnStyle],
isShadowVisible ? styles.largeBtnShadow : null,
{ width: btnWidth },
]}
>
<TouchableOpacity onPress={pressHandler}>
<LinearGradient
colors={themeColor.gradientColor[bgColor]}
start={[0.1, 0.9]}
end={[0.9, 0.1]}
style={{ borderRadius: 10, padding: 20 }}
>
<Text style={styles.largeBtnFont}>{subtitle}</Text>
<Text style={styles.largeBtnHeader}>
{title}
</Text>
<Text style={styles.largeBtnFont}>{note}</Text>
</LinearGradient>
</TouchableOpacity>
</View>

);
}

Expand All @@ -33,6 +42,8 @@ LargeButton.propTypes = {
note: PropTypes.string,
bgColor: PropTypes.string,
btnWidth: PropTypes.string,
pressHandler: PropTypes.func.isRequired,
isShadowVisible: PropTypes.bool.isRequired,
};

LargeButton.defaultProps = {
Expand Down
10 changes: 3 additions & 7 deletions src/Common/themeStyle.js
Original file line number Diff line number Diff line change
Expand Up @@ -83,18 +83,14 @@ const styles = StyleSheet.create({
redLargeBtn: {
marginTop: 20,
shadowColor: '#f38aa9',
shadowOffset: {
width: 0,
height: 6,
},
shadowOpacity: 0.70,
shadowRadius: 4.65,
elevation: 8,
},

greenLargeBtn: {
marginTop: 20,
shadowColor: '#70ea93',
},

largeBtnShadow: {
shadowOffset: {
width: 0,
height: 6,
Expand Down
33 changes: 30 additions & 3 deletions src/Stats/FilterBtn.jsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,40 @@
import React from 'react';
import PropTypes from 'prop-types';
import LargeButton from '../Common/LargeBtn';

export default function FilterBtn() {
export default function FilterBtn({
currentFilter, onFilterChange, totalExpense, totalIncome,
}) {
const numberOfBtns = 2;
const btnWidth = `${100 / numberOfBtns - 2}%`;

return (
<>
<LargeButton subtitle="Spent" title="-$400.00" note="Expense" bgColor="red" btnWidth={btnWidth} />
<LargeButton subtitle="Earned" title="+$680.00" note="Incomes" bgColor="green" btnWidth={btnWidth} />
<LargeButton
subtitle="Spent"
title={`-$${totalExpense}`}
note="Expense"
bgColor="red"
btnWidth={btnWidth}
isShadowVisible={currentFilter === 'Expense'}
pressHandler={() => onFilterChange('Expense')}
/>
<LargeButton
subtitle="Earned"
title={`+$${totalIncome}`}
note="Income"
bgColor="green"
btnWidth={btnWidth}
isShadowVisible={currentFilter === 'Income'}
pressHandler={() => onFilterChange('Income')}
/>
</>
);
}

FilterBtn.propTypes = {
currentFilter: PropTypes.string.isRequired,
onFilterChange: PropTypes.func.isRequired,
totalExpense: PropTypes.number.isRequired,
totalIncome: PropTypes.number.isRequired,
};
32 changes: 27 additions & 5 deletions src/Stats/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,18 +17,35 @@ export default function Stats() {
const [view, setCurrentView] = useState('month');
const [timePeriodOptions, setTimePeriod] = useState(utils.getDateSet(moment(), view));
const [isOverlayVisible, setOverlayVisibility] = useState(false);
const [transFilter, setTransFilter] = useState('all');

const updateHeaderView = (type) => {
setCurrentView(type);
setTimePeriod(utils.getDateSet(moment(), type));
setOverlayVisibility(!isOverlayVisible);
};

const filterListView = (transactionRecords) => {
const current = timePeriodOptions[1];
return utils.filterData(transactionRecords, current, view);
const filterTransactions = (transactionsList) => {
const transactionsWithSpecificType = utils.filterTransactionByType(
transactionsList,
transFilter,
);
return utils.filterTransactionsByDate(
transactionsWithSpecificType,
timePeriodOptions[1],
view,
);
};

const calculateSumByType = (dataList, type) => dataList
.filter((item) => item.type === type)
.reduce((sum, { amount }) => sum + parseFloat(amount), 0);

const filteredTransactions = filterTransactions(transactions);
const processedTransactions = utils.groupTransactionsByDate(filteredTransactions);
const totalExpense = calculateSumByType(filteredTransactions, 'Expense');
const totalIncome = calculateSumByType(filteredTransactions, 'Income');

return (
<View style={{ flex: 1, flexDirection: 'column' }}>
<Overlay height={200} isVisible={isOverlayVisible}>
Expand All @@ -51,12 +68,17 @@ export default function Stats() {
<ScrollView style={styles.deviceBody}>
<View style={{ marginBottom: 20 }}>
<View style={{ flexDirection: 'row', justifyContent: 'space-between' }}>
<FilterBtn />
<FilterBtn
currentFilter={transFilter}
onFilterChange={(newFilter) => (newFilter === transFilter ? setTransFilter('all') : setTransFilter(newFilter))}
totalExpense={totalExpense}
totalIncome={totalIncome}
/>
</View>
{(transactions.length !== 0)
? (
<TransList
transactions={filterListView(utils.groupTransactionsByDate(transactions))}
transactions={processedTransactions}
/>
)
: <EmptyHistory />}
Expand Down
18 changes: 9 additions & 9 deletions src/Stats/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,30 +41,30 @@ const getDateSet = (current, type) => [
current.clone().add(1, type),
];

const filterData = (dataList, range, view) => {
const filterTransactionsByDate = (dataList, range, view) => {
const monthRange = range.format('MMM YYYY');
const yearRange = range.format('YYYY');
let result;

switch (view) {
case 'month':
result = dataList.filter((value) => moment(value[0].date, 'MMMM Do YYYY').format('MMM YYYY') === monthRange);
break;
return dataList.filter((value) => moment.unix(value.date).format('MMM YYYY') === monthRange);
case 'year':
result = dataList.filter((value) => moment(value[0].date, 'MMMM Do YYYY').format('YYYY') === yearRange);
break;
return dataList.filter((value) => moment.unix(value.date).format('YYYY') === yearRange);
default:
break;
return [];
}
return result;
};

const filterTransactionByType = (dataList, type) => (type === 'all' ? dataList : dataList.filter((item) => (item.type === type)));

const transType = (amount, type) => (type === 'Expense' ? `-$${amount}` : `+$${amount}`);

export default {
sortDataByDate,
sumAmount,
groupTransactionsByDate,
getDateSet,
filterData,
filterTransactionsByDate,
filterTransactionByType,
transType,
};

0 comments on commit 15b0a8f

Please sign in to comment.