Skip to content

Instantly share code, notes, and snippets.

@diogobruni
Last active July 23, 2018 19:09
Show Gist options
  • Save diogobruni/dcdd1277949b5c564b662bc370d346cb to your computer and use it in GitHub Desktop.
Save diogobruni/dcdd1277949b5c564b662bc370d346cb to your computer and use it in GitHub Desktop.
import React from 'react'
import { Scene, Stack, Drawer } from 'react-native-router-flux'
import { Icon } from 'native-base'
import DefaultProps from '../constants/navigation'
import AppConfig from '../../constants/config'
//import DrawerComponent from '../components/MyDrawer'
import Sidebar from '../components/Sidebar'
import DashboardContainer from '../../containers/Dashboard'
import DashboardComponent from '../components/Dashboard'
import PanelFacebookAdsContainer from '../../containers/PanelFacebookAds'
import PanelFacebookAdsComponent from '../components/PanelFacebookAds'
import PanelGoogleAdsenseContainer from '../../containers/PanelGoogleAdsense'
import PanelGoogleAdsenseComponent from '../components/PanelGoogleAdsense'
import PanelMonetizzeContainer from '../../containers/PanelMonetizze'
import PanelMonetizzeComponent from '../components/PanelMonetizze'
import { ActionConst } from 'react-native-router-flux'
const Dashboard = (
<Stack>
<Scene hideNavBar>
<Drawer
key="drawer"
contentComponent={Sidebar}
drawerIcon={() => <Icon name="menu" />}
drawerWidth={320}
>
<Scene hideNavBar panHandlers={null}>
<Scene
key="dashboard"
title="Painel Integrado"
type={ActionConst.REPLACE}
component={DashboardContainer}
Layout={DashboardComponent}
/>
<Stack
key="facebookAds"
title="Facebook Ads #Drawer"
icon={() => <Icon name="book" {...DefaultProps.icons} />}
{...DefaultProps.navbarProps}
>
<Scene key="facebookAds" component={PanelFacebookAdsContainer} Layout={PanelFacebookAdsComponent} />
</Stack>
</Scene>
</Drawer>
</Scene>
</Stack>
)
export default Dashboard
import React from 'react'
import PropTypes from 'prop-types'
import ReactNative, { Image, StyleSheet } from 'react-native'
/* Import Modules */
// --
/* Import Constants */
import messages from '../../constants/messages'
/* Import Actions */
import { Actions } from 'react-native-router-flux'
/* Import UI Components */
import { Container, Header, Title, Content, Left, Body, Right, View, Text, Button, Icon, Item, Label, Card, CardItem, Grid, Col, Row, Picker, Form, H2 } from 'native-base'
import { translate } from '../../i18n'
import Loading from './Loading'
//import LoadingOverlay from './LoadingOverlay'
import LoadingContent from './pieces/LoadingContent'
import NoData from './pieces/NoData'
import Messages from './Messages'
//import MyDrawer from './MyDrawer'
import Navbar from './Navbar'
import DatePicker from 'react-native-datepicker'
import MosaicBlock from './pieces/MosaicBlock'
import Divider from './pieces/Divider'
/* Import Styles */
import { cssColors, cssDevice, cssUtils, cssSkeleton, cssStyles } from '../styles'
/* END OF IMPORTS */
// --
/* DATA CONTROL */
import { getObjectValueOrDefault, getVarOrDefault } from '../../lib/renderAuxLib'
// --
/* END OF DATA CONTROL */
class Dashboard extends React.Component {
static propTypes = {
locale: PropTypes.string,
user: PropTypes.object.isRequired,
loading: PropTypes.bool.isRequired,
info: PropTypes.string,
error: PropTypes.string,
success: PropTypes.string,
filters: PropTypes.object,
panels: PropTypes.object,
setDateStart: PropTypes.func.isRequired,
setDateEnd: PropTypes.func.isRequired,
setPanelId: PropTypes.func.isRequired,
getPanelData: PropTypes.func.isRequired,
getCustomPanelList: PropTypes.func.isRequired,
openDrawer: PropTypes.func.isRequired,
}
static defaultProps = {
error: null,
locale: null,
user: {},
}
constructor(props) {
super(props)
this.state = {
sceneName: 'dashboard',
sceneTitle: 'Painel Integrado'
}
this.handleChangeDateStart = this.handleChangeDateStart.bind(this)
this.handleChangeDateEnd = this.handleChangeDateEnd.bind(this)
this.handleChangePanelId = this.handleChangePanelId.bind(this)
}
handleChangeDateStart(value) {
this.props.setDateStart(value, this.props.filters.dateEnd)
}
handleChangeDateEnd(value) {
this.props.setDateEnd(this.props.filters.dateStart, value)
}
handleChangePanelId(value) {
this.props.setPanelId(value)
}
manageGetPanelData(panelId, dateStart, dateEnd) {
const params = {
panelId,
dateStart,
dateEnd,
}
return this.props.getPanelData(params)
}
componentDidMount() {
//this.props.getCustomPanelList()
/* react-native-router-flux param // Not Working */
const { actionPanel } = this.props
if (actionPanel) {
this.handleChangePanelId(actionPanel)
} else {
this.manageGetPanelData(this.props.filters.panelId, this.props.filters.dateStart, this.props.filters.dateEnd)
}
/*const interval = setInterval(function() {
// React Native Timer Hack // Interval of 5 minutes
let hackDate = new Date()
if (hackDate.getMinutes() % 5 == 0) {
if (Actions.currentScene == this.state.sceneName) {
this.manageGetPanelData(this.props.filters.panelId, this.props.filters.dateStart, this.props.filters.dateEnd)
} else {
clearInterval(interval)
}
}
}.bind(this), 1 * 60 * 1000)*/
}
componentDidUpdate(prevProps, prevState, snapshot) {
if (
prevProps.filters.panelId != this.props.filters.panelId ||
prevProps.filters.dateStart != this.props.filters.dateStart ||
prevProps.filters.dateEnd != this.props.filters.dateEnd
) {
this.manageGetPanelData(this.props.filters.panelId, this.props.filters.dateStart, this.props.filters.dateEnd)
}
}
renderPanelPicker(list) {
let componentHtml = []
if (list) {
componentHtml = list.map(item => {
return (
<Picker.Item key={item.id} label={item.name} value={item.id} />
)
})
}
return componentHtml
}
renderSpendChildren(data, maxCols) {
const fields = [
{
key: 'facebook_ads_spend',
placeholder: 'facebook_ads'
}
]
return this.renderChildrenCols('spend_', data, maxCols, fields)
}
renderEarnChildren(data, maxCols) {
const fields = [
{
key: 'google_adsense_earn',
placeholder: 'google_adsense'
},
{
key: 'monetizze_earn',
placeholder: 'monetizze'
}
]
return this.renderChildrenCols('earn_', data, maxCols, fields)
}
renderChildrenCols(type, data, maxCols, fields) {
const arImageIcons = {
facebook_ads: require('../../images/50/platform-facebook-ads-50-color.png'),
google_adsense: require('../../images/50/platform-adsense-50-color.png'),
monetizze: require('../../images/50/platform-monetizze-50-color.png'),
}
const childrenCols = (function() {
let html = []
if (data) {
for (let field of fields) {
if (data[field.key]) {
const fieldData = data[field.key]
html.push(
<Col key={`${type}${field.key}`} style={[cssSkeleton.col, cssSkeleton.firstCol]}>
<Row style={cssStyles.mosaicRow}>
<MosaicBlock>
<Image source={arImageIcons[field.placeholder]} style={[cssStyles.mosaicImageIcon]} />
<Text style={cssStyles.mosaicMediumText}>{fieldData.formattedValue}</Text>
</MosaicBlock>
</Row>
</Col>
)
}
}
}
return html
})()
const auxChildrenEmpty = (function(iMax, iPrinted) {
let html = []
for (let i = iPrinted; i < iMax; i++) {
html.push(<Col key={`aux_${type}${i}`}></Col>)
}
return html
})(maxCols, childrenCols.length)
return [ childrenCols, auxChildrenEmpty ]
}
render() {
const { loading, error, locale, filters, panels } = this.props
const { sceneTitle } = this.state
let panelData = panels.panels[filters.panelId] || false
if (
panelData &&
panelData.earn &&
panelData.earn.value == 0 &&
panelData.spend &&
panelData.spend.value == 0
) {
panelData = false
}
/* FILTER PANEL */
let pickerPanelList = this.renderPanelPicker(filters.customPanelList)
/* SPEND */
const maxSpendChildrenCols = 2
const [ spendPlatformList, auxSpendPlatformCols ] = this.renderSpendChildren(panelData, maxSpendChildrenCols)
/* EARN */
const maxEarnChildrenCols = 2
const [ earnPlatformList, auxEarnPlatformCols ] = this.renderEarnChildren(panelData, maxEarnChildrenCols)
//if (loading) return <Loading />
return (
<Container>
<Navbar
title={sceneTitle}
openDrawer={Actions.drawerOpen}
/>
<Content padder>
{
//error && <Messages message={error} />
}
<Card transparent>
<CardItem header style={[cssUtils.center]}>
<Text style={[cssUtils.defaultTextStyle, cssStyles.filterLabel]}>Selecione o período e a conta desejada</Text>
</CardItem>
<CardItem>
<Body style={[cssUtils.center]}>
<Form>
<Item style={[cssUtils.noBorder, cssUtils.center, { marginLeft: 0 }]}>
<DatePicker
//style={{width: 200}}
date={filters.dateStart}
mode="date"
placeholder="Selecione a data inicial"
format="DD/MM/YYYY"
//minDate="2016-05-01"
//maxDate="2016-06-01"
confirmBtnText="Confirmar"
cancelBtnText="Cancelar"
style={datePickerStyle}
customStyles={datePickerExtraStyle}
onDateChange={this.handleChangeDateStart}
/>
<Text style={[cssUtils.defaultTextStyle, cssStyles.datepickerSeparatorText]}>
até
</Text>
<DatePicker
//style={{width: 200}}
date={filters.dateEnd}
mode="date"
placeholder="Selecione a data final"
format="DD/MM/YYYY"
//minDate="2016-05-01"
//maxDate="2016-06-01"
confirmBtnText="Confirmar"
cancelBtnText="Cancelar"
style={datePickerStyle}
customStyles={datePickerExtraStyle}
onDateChange={this.handleChangeDateEnd}
/>
</Item>
<Picker
iosHeader="Select one"
mode="dropdown"
selectedValue={filters.panelId}
onValueChange={this.handleChangePanelId}
style={[cssStyles.dropdownPicker, {marginTop: 10}]}
>
<Picker.Item label="Painel principal" value="dashboard" />
{pickerPanelList}
</Picker>
</Form>
</Body>
</CardItem>
</Card>
{loading &&
<LoadingContent />
}
{panelData &&
<View>
<H2 style={cssStyles.sectionTitle}>Resultados</H2>
<Grid>
<Col style={[cssSkeleton.col, cssSkeleton.firstCol]}>
<Row style={cssStyles.mosaicRow}>
<MosaicBlock>
<Text style={[cssStyles.mosaicBigText, panelData.revenue.value > 0 ? cssStyles.textProfit : cssStyles.textWaste]}>
{getObjectValueOrDefault(panelData, 'revenue')}
</Text>
<Text style={[cssStyles.mosaicSmallText]}>Rendimento</Text>
</MosaicBlock>
</Row>
</Col>
<Col style={[cssSkeleton.col, cssSkeleton.firstCol]}>
<Row style={cssStyles.mosaicRow}>
<MosaicBlock>
<Text style={[cssStyles.mosaicBigText, panelData.roi.value > 0 ? cssStyles.textProfit : cssStyles.textWaste]}>
{getObjectValueOrDefault(panelData, 'roi')}
</Text>
<Text style={cssStyles.mosaicSmallText}>ROI</Text>
</MosaicBlock>
</Row>
</Col>
</Grid>
<H2 style={cssStyles.sectionTitle}>Investimentos</H2>
<MosaicBlock>
<Text style={cssStyles.mosaicBigText}>
{getObjectValueOrDefault(panelData, 'spend')}
</Text>
<Text style={cssStyles.mosaicSmallText}>Total</Text>
</MosaicBlock>
<Grid>
{spendPlatformList}
{auxSpendPlatformCols}
</Grid>
<H2 style={cssStyles.sectionTitle}>Receita</H2>
<MosaicBlock>
<Text style={cssStyles.mosaicBigText}>
{getObjectValueOrDefault(panelData, 'earn')}
</Text>
<Text style={cssStyles.mosaicSmallText}>Total</Text>
</MosaicBlock>
<Grid>
{earnPlatformList}
{auxEarnPlatformCols}
</Grid>
</View>
}
{!loading && !panelData &&
<NoData
text={messages.noPanelData}
/>
}
</Content>
</Container>
);
}
}
const datePickerStyle = {
//width: 130
alignSelf: 'stretch'
}
const datePickerExtraStyle = {
dateIcon: {
display: 'none',
},
dateInput: {
marginLeft: 0,
borderWidth: 0,
backgroundColor: cssColors.main,
},
dateText: {
color: '#FFF'
},
placeholderText: {
color: '#FFF'
}
}
const localStyles = StyleSheet.create({
})
export default Dashboard;
import React,{ Component } from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import { setDateStart, setDateEnd, setPanelId, getCustomPanelList } from '../actions/filters'
import { getPanelData } from '../actions/panels'
import { openDrawer, closeDrawer } from '../actions/drawer'
class Dashboard extends Component {
static propTypes = {
Layout: PropTypes.func.isRequired,
locale: PropTypes.string,
user: PropTypes.object.isRequired,
loading: PropTypes.bool.isRequired,
info: PropTypes.string,
error: PropTypes.string,
success: PropTypes.string,
filters: PropTypes.object,
panels: PropTypes.object,
setDateStart: PropTypes.func.isRequired,
setDateEnd: PropTypes.func.isRequired,
setPanelId: PropTypes.func.isRequired,
getPanelData: PropTypes.func.isRequired,
getCustomPanelList: PropTypes.func.isRequired,
openDrawer: PropTypes.func.isRequired,
}
render = () => {
const {
Layout,
locale,
user,
loading,
info,
error,
success,
filters,
panels,
setDateStart,
setDateEnd,
setPanelId,
getPanelData,
getCustomPanelList,
openDrawer,
} = this.props;
return <Layout
locale={locale}
user={user}
loading={loading}
info={info}
error={error}
success={success}
filters={filters}
panels={panels}
setDateStart={setDateStart}
setDateEnd={setDateEnd}
setPanelId={setPanelId}
getPanelData={getPanelData}
getCustomPanelList={getCustomPanelList}
openDrawer={openDrawer}
/>;
}
}
const mapStateToProps = state => ({
locale: state.locale || null,
user: state.user || {},
loading: state.status.loading || false,
info: state.status.info || null,
error: state.status.error || null,
success: state.status.success || null,
filters: state.filters || {},
panels: state.panels || {},
})
const mapDispatchToProps = {
setDateStart,
setDateEnd,
setPanelId,
getPanelData,
getCustomPanelList,
openDrawer,
}
export default connect(mapStateToProps, mapDispatchToProps)(Dashboard)
import * as Expo from 'expo';
import React, { Component } from 'react';
import { StatusBar, Platform } from 'react-native';
import PropTypes from 'prop-types';
import { Provider } from 'react-redux';
import { Router, Stack, Reducer } from 'react-native-router-flux';
import { PersistGate } from 'redux-persist/es/integration/react';
import { Root, StyleProvider } from 'native-base';
import getTheme from '../../native-base-theme/components';
import theme from '../../native-base-theme/variables/commonColor';
import Splash from './routes/splash';
import Login from './routes/login';
import Dashboard from './routes/dashboard';
import Loading from './components/Loading';
// Hide StatusBar on Android as it overlaps tabs
if (Platform.OS === 'android') StatusBar.setHidden(true);
const reducerCreate = params => {
const defaultReducer = new Reducer(params)
return (state, action) => {
return defaultReducer(state, action)
}
}
export default class App extends Component {
static propTypes = {
store: PropTypes.shape({}).isRequired,
persistor: PropTypes.shape({}).isRequired,
}
constructor() {
super()
this.state = {
isReady: false
}
}
componentWillMount() {
this.loadFonts();
}
async loadFonts() {
await Expo.Font.loadAsync({
Roboto: require("native-base/Fonts/Roboto.ttf"),
Roboto_light: require("../fonts/Roboto-Light.ttf"),
Roboto_thin: require("../fonts/Roboto-Thin.ttf"),
Roboto_medium: require("native-base/Fonts/Roboto_medium.ttf"),
Ionicons: require("@expo/vector-icons/fonts/Ionicons.ttf")
});
this.setState({ isReady: true });
}
render() {
const { store, persistor } = this.props
if (!this.state.isReady) {
return <Expo.AppLoading />;
}
return (
<Root>
<Provider store={store}>
<PersistGate
loading={<Loading />}
persistor={persistor}
>
<StyleProvider style={getTheme(theme)}>
<Router createReducer={reducerCreate}>
<Stack key="root">
{Splash}
{Login}
{Dashboard}
</Stack>
</Router>
</StyleProvider>
</PersistGate>
</Provider>
</Root>
)
}
}
/*
const App = ({ store, persistor }) => (
<Root>
<Provider store={store}>
<PersistGate
loading={<Loading />}
persistor={persistor}
>
<StyleProvider style={getTheme(theme)}>
<Router>
<Stack key="root">
{Login}
{Index}
</Stack>
</Router>
</StyleProvider>
</PersistGate>
</Provider>
</Root>
);
App.propTypes = {
store: PropTypes.shape({}).isRequired,
persistor: PropTypes.shape({}).isRequired,
};
export default App;
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment