diff --git a/app/javascript/gabsocial/actions/expenses.js b/app/javascript/gabsocial/actions/expenses.js new file mode 100644 index 00000000..b7ff97c0 --- /dev/null +++ b/app/javascript/gabsocial/actions/expenses.js @@ -0,0 +1,35 @@ +import api from '../api' +import { me } from '../initial_state' + +export const EXPENSES_FETCH_REQUEST = 'EXPENSES_FETCH_REQUEST' +export const EXPENSES_FETCH_SUCCESS = 'EXPENSES_FETCH_SUCCESS' +export const EXPENSES_FETCH_FAIL = 'EXPENSES_FETCH_FAIL' + +/** + * Fetch monthly expenses completion + */ +export const fetchExpenses = () => (dispatch, getState) => { + if (!me) return + + dispatch(fetchExpensesRequest()) + + api(getState).get('/api/v1/expenses').then((response) => { + dispatch(fetchExpensesSuccess(response.data.expenses)) + }).catch((error) => { + dispatch(fetchExpensesFail(error)) + }) +} + +const fetchExpensesRequest = () => ({ + type: EXPENSES_FETCH_REQUEST, +}) + +const fetchExpensesSuccess = (value) => ({ + type: EXPENSES_FETCH_SUCCESS, + value, +}) + +const fetchExpensesFail = (error, listType) => ({ + type: EXPENSES_FETCH_FAIL, + error, +}) \ No newline at end of file diff --git a/app/javascript/gabsocial/components/panel/progress_panel.js b/app/javascript/gabsocial/components/panel/progress_panel.js index 96a59f8b..3e9062d8 100644 --- a/app/javascript/gabsocial/components/panel/progress_panel.js +++ b/app/javascript/gabsocial/components/panel/progress_panel.js @@ -1,11 +1,12 @@ import React from 'react' import PropTypes from 'prop-types' +import { connect } from 'react-redux' import { injectIntl, defineMessages } from 'react-intl' -import { monthlyExpensesComplete } from '../../initial_state' import { URL_DISSENTER_SHOP, URL_DISSENTER_SHOP_DONATIONS, } from '../../constants' +import { fetchExpenses } from '../../actions/expenses' import PanelLayout from './panel_layout'; import ProgressBar from '../progress_bar' import Button from '../button' @@ -14,12 +15,17 @@ import Icon from '../icon' class ProgressPanel extends React.PureComponent { + componentDidMount() { + if (!this.props.isFetched) { + this.props.onFetchExpenses() + } + } + render() { - const { intl } = this.props + const { intl, value, isFetched } = this.props - if (!monthlyExpensesComplete) return null + if (value === 0 && !isFetched) return null - const value = Math.min(parseFloat(monthlyExpensesComplete), 100) const subtitle = (
@@ -46,7 +52,7 @@ class ProgressPanel extends React.PureComponent { >
@@ -64,8 +70,22 @@ const messages = defineMessages({ donationTitle: { id: 'make_donation', defaultMessage: 'Make a Donation' }, }) +const mapStateToProps = (state) => ({ + isFetched: state.getIn(['expenses', 'fetched'], false), + value: state.getIn(['expenses', 'value'], 0), +}) + +const mapDispatchToProps = (dispatch) => ({ + onFetchExpenses() { + dispatch(fetchExpenses()) + }, +}) + ProgressPanel.propTypes = { intl: PropTypes.object.isRequired, + isFetched: PropTypes.bool.isRequired, + value: PropTypes.number.isRequired, + onFetchExpenses: PropTypes.func.isRequired, } -export default injectIntl(ProgressPanel) \ No newline at end of file +export default injectIntl(connect(mapStateToProps, mapDispatchToProps)(ProgressPanel)) \ No newline at end of file diff --git a/app/javascript/gabsocial/components/timeline_injections/progress_injection.js b/app/javascript/gabsocial/components/timeline_injections/progress_injection.js index ae86bfd5..ed63213a 100644 --- a/app/javascript/gabsocial/components/timeline_injections/progress_injection.js +++ b/app/javascript/gabsocial/components/timeline_injections/progress_injection.js @@ -1,11 +1,12 @@ import React from 'react' import PropTypes from 'prop-types' +import { connect } from 'react-redux' import { injectIntl, defineMessages } from 'react-intl' -import { monthlyExpensesComplete } from '../../initial_state' import { URL_DISSENTER_SHOP, URL_DISSENTER_SHOP_DONATIONS, } from '../../constants' +import { fetchExpenses } from '../../actions/expenses' import TimelineInjectionLayout from './timeline_injection_layout' import ProgressBar from '../progress_bar' import Button from '../button' @@ -13,17 +14,24 @@ import Text from '../text' class ProgressInjection extends React.PureComponent { + componentDidMount() { + const { isFetched, isXS } = this.props + if (!isFetched && isXS) { + this.props.onFetchExpenses() + } + } + render() { const { intl, isXS, + value, + isFetched, injectionId, } = this.props - if (!monthlyExpensesComplete || !isXS) return
+ if ((value === 0 && isFetched) || !isXS) return
- const value = Math.min(parseFloat(monthlyExpensesComplete), 100) - return (
@@ -53,8 +61,23 @@ const messages = defineMessages({ donationTitle: { id: 'make_donation', defaultMessage: 'Make a Donation' }, }) +const mapStateToProps = (state) => ({ + isFetched: state.getIn(['expenses', 'fetched'], false), + value: state.getIn(['expenses', 'value'], 0), +}) + +const mapDispatchToProps = (dispatch) => ({ + onFetchExpenses() { + dispatch(fetchExpenses()) + }, +}) + ProgressInjection.propTypes = { injectionId: PropTypes.string.isRequired, + intl: PropTypes.object.isRequired, + isFetched: PropTypes.bool.isRequired, + value: PropTypes.number.isRequired, + onFetchExpenses: PropTypes.func.isRequired, } -export default injectIntl(ProgressInjection) \ No newline at end of file +export default injectIntl(connect(mapStateToProps, mapDispatchToProps)(ProgressInjection)) \ No newline at end of file diff --git a/app/javascript/gabsocial/initial_state.js b/app/javascript/gabsocial/initial_state.js index 90ba9805..b42ee17a 100644 --- a/app/javascript/gabsocial/initial_state.js +++ b/app/javascript/gabsocial/initial_state.js @@ -19,7 +19,6 @@ export const version = getMeta('version'); export const isStaff = getMeta('is_staff'); export const unreadCount = getMeta('unread_count'); export const lastReadNotificationId = getMeta('last_read_notification_id'); -export const monthlyExpensesComplete = getMeta('monthly_expenses_complete'); export const trendingHashtags = getMeta('trending_hashtags'); export const isFirstSession = getMeta('is_first_session'); export const emailConfirmed = getMeta('email_confirmed'); diff --git a/app/javascript/gabsocial/reducers/expenses.js b/app/javascript/gabsocial/reducers/expenses.js new file mode 100644 index 00000000..70c67d04 --- /dev/null +++ b/app/javascript/gabsocial/reducers/expenses.js @@ -0,0 +1,23 @@ +import { Map as ImmutableMap } from 'immutable' +import { + EXPENSES_FETCH_REQUEST, + EXPENSES_FETCH_SUCCESS, + EXPENSES_FETCH_FAIL, +} from '../actions/expenses' + +const initialState = ImmutableMap({ + fetched: false, + value: 0, +}) + +export default function expenses(state = initialState, action) { + switch (action.type) { + case EXPENSES_FETCH_REQUEST: + case EXPENSES_FETCH_FAIL: + return state.set('fetched', true).set('value', 0) + case EXPENSES_FETCH_SUCCESS: + return state.set('fetched', true).set('value', action.value) + default: + return state + } +} diff --git a/app/javascript/gabsocial/reducers/index.js b/app/javascript/gabsocial/reducers/index.js index 7c7f5358..44f95b9d 100644 --- a/app/javascript/gabsocial/reducers/index.js +++ b/app/javascript/gabsocial/reducers/index.js @@ -15,6 +15,7 @@ import compose from './compose' import contexts from './contexts' import custom_emojis from './custom_emojis' import deck from './deck' +import expenses from './expenses' import filters from './filters' import groups from './groups' import group_categories from './group_categories' @@ -70,6 +71,7 @@ const reducers = { contexts, custom_emojis, deck, + expenses, filters, groups, group_categories,