From 0d97c084c209ee5bf5edec44f13e7e8c4ff59781 Mon Sep 17 00:00:00 2001 From: Alejandro Celaya Date: Sat, 1 Sep 2018 11:08:27 +0200 Subject: [PATCH] Extracted components in ShortUrlVisits to simplify maintainability --- src/visits/GraphCard.js | 48 +++++++++++++++ src/visits/ShortUrlVisits.js | 116 ++++++----------------------------- src/visits/VisitsHeader.js | 53 ++++++++++++++++ src/visits/VisitsHeader.scss | 3 + 4 files changed, 124 insertions(+), 96 deletions(-) create mode 100644 src/visits/GraphCard.js create mode 100644 src/visits/VisitsHeader.js create mode 100644 src/visits/VisitsHeader.scss diff --git a/src/visits/GraphCard.js b/src/visits/GraphCard.js new file mode 100644 index 00000000..52a87436 --- /dev/null +++ b/src/visits/GraphCard.js @@ -0,0 +1,48 @@ +import { Card, CardHeader, CardBody } from 'reactstrap'; +import { Doughnut, HorizontalBar } from 'react-chartjs-2'; +import PropTypes from 'prop-types'; +import React from 'react'; + +const propTypes = { + title: PropTypes.string, + isBarChart: PropTypes.bool, + stats: PropTypes.object, +}; + +export function GraphCard({ title, isBarChart, stats }) { + const generateGraphData = (stats) => ({ + labels: Object.keys(stats), + datasets: [ + { + title, + data: Object.values(stats), + backgroundColor: isBarChart ? 'rgba(70, 150, 229, 0.4)' : [ + '#97BBCD', + '#DCDCDC', + '#F7464A', + '#46BFBD', + '#FDB45C', + '#949FB1', + '#4D5360', + ], + borderColor: isBarChart ? 'rgba(70, 150, 229, 1)' : 'white', + borderWidth: 2, + }, + ], + }); + const renderGraph = () => { + const Component = isBarChart ? HorizontalBar : Doughnut; + const legend = isBarChart ? { display: false } : { position: 'right' }; + + return ; + }; + + return ( + + {title} + {renderGraph()} + + ); +} + +GraphCard.propTypes = propTypes; diff --git a/src/visits/ShortUrlVisits.js b/src/visits/ShortUrlVisits.js index 90ea51b7..7a5aaef7 100644 --- a/src/visits/ShortUrlVisits.js +++ b/src/visits/ShortUrlVisits.js @@ -2,23 +2,22 @@ import preloader from '@fortawesome/fontawesome-free-solid/faCircleNotch'; import FontAwesomeIcon from '@fortawesome/react-fontawesome'; import { isEmpty, mapObjIndexed, pick } from 'ramda'; import React from 'react'; -import { Doughnut, HorizontalBar } from 'react-chartjs-2'; -import Moment from 'react-moment'; import { connect } from 'react-redux'; -import { Card, CardBody, CardHeader, UncontrolledTooltip } from 'reactstrap'; +import { Card } from 'reactstrap'; import PropTypes from 'prop-types'; import DateInput from '../common/DateInput'; import MutedMessage from '../utils/MuttedMessage'; -import ExternalLink from '../utils/ExternalLink'; import { serverType } from '../servers/prop-types/index'; import { getShortUrlVisits, shortUrlVisitsType } from './reducers/shortUrlVisits'; import { - processOsStats, processBrowserStats, processCountriesStats, + processOsStats, processReferrersStats, } from './services/VisitsParser'; import './ShortUrlVisits.scss'; +import { VisitsHeader } from './VisitsHeader'; +import { GraphCard } from './GraphCard'; export class ShortUrlsVisitsComponent extends React.Component { static propTypes = { @@ -60,59 +59,12 @@ export class ShortUrlsVisitsComponent extends React.Component { processBrowserStats, processCountriesStats, processReferrersStats, - shortUrlVisits: { visits, loading, error, shortUrl }, + shortUrlVisits, } = this.props; + const { visits, loading, error } = shortUrlVisits; const serverUrl = selectedServer ? selectedServer.url : ''; const shortLink = `${serverUrl}/${params.shortCode}`; - const generateGraphData = (stats, label, isBarChart) => ({ - labels: Object.keys(stats), - datasets: [ - { - label, - data: Object.values(stats), - backgroundColor: isBarChart ? 'rgba(70, 150, 229, 0.4)' : [ - '#97BBCD', - '#DCDCDC', - '#F7464A', - '#46BFBD', - '#FDB45C', - '#949FB1', - '#4D5360', - ], - borderColor: isBarChart ? 'rgba(70, 150, 229, 1)' : 'white', - borderWidth: 2, - }, - ], - }); - const renderGraphCard = (title, stats, isBarChart, label) => ( -
- - {title} - - {!isBarChart && ( - - )} - {isBarChart && ( - - )} - - -
- ); + const renderContent = () => { if (loading) { return Loading...; @@ -132,53 +84,25 @@ export class ShortUrlsVisitsComponent extends React.Component { return (
- {renderGraphCard('Operating systems', processOsStats(visits), false)} - {renderGraphCard('Browsers', processBrowserStats(visits), false)} - {renderGraphCard('Countries', processCountriesStats(visits), true, 'Visits')} - {renderGraphCard('Referrers', processReferrersStats(visits), true, 'Visits')} +
+ +
+
+ +
+
+ +
+
+ +
); }; - const renderCreated = () => ( - - {shortUrl.dateCreated} - - {shortUrl.dateCreated} - - - ); - return (
-
- - -

- { - shortUrl.visitsCount && - Visits: {shortUrl.visitsCount} - } - Visit stats for {shortLink} -

-
- {shortUrl.dateCreated && ( -
- Created: -   - {loading && Loading...} - {!loading && renderCreated()} -
- )} -
- Long URL: -   - {loading && Loading...} - {!loading && {shortUrl.longUrl}} -
-
-
-
+
diff --git a/src/visits/VisitsHeader.js b/src/visits/VisitsHeader.js new file mode 100644 index 00000000..30dbd412 --- /dev/null +++ b/src/visits/VisitsHeader.js @@ -0,0 +1,53 @@ +import { Card, UncontrolledTooltip } from 'reactstrap'; +import Moment from 'react-moment'; +import React from 'react'; +import PropTypes from 'prop-types'; +import ExternalLink from '../utils/ExternalLink'; +import { shortUrlVisitsType } from './reducers/shortUrlVisits'; +import './VisitsHeader.scss'; + +const propTypes = { + shortUrlVisits: shortUrlVisitsType, + shortLink: PropTypes.string, +}; + +export function VisitsHeader({ shortUrlVisits, shortLink }) { + const { shortUrl, loading } = shortUrlVisits; + const renderDate = () => ( + + {shortUrl.dateCreated} + + {shortUrl.dateCreated} + + + ); + + return ( +
+ +

+ {shortUrl.visitsCount && + Visits: {shortUrl.visitsCount}} + Visit stats for {shortLink} +

+
+ {shortUrl.dateCreated && ( +
+ Created: +   + {loading && Loading...} + {!loading && renderDate()} +
+ )} +
+ Long URL: +   + {loading && Loading...} + {!loading && {shortUrl.longUrl}} +
+
+
+ ); +} + +VisitsHeader.propTypes = propTypes; diff --git a/src/visits/VisitsHeader.scss b/src/visits/VisitsHeader.scss new file mode 100644 index 00000000..51dcc29f --- /dev/null +++ b/src/visits/VisitsHeader.scss @@ -0,0 +1,3 @@ +.visits-header__created-at { + cursor: default; +}