mirror of
https://github.com/shlinkio/shlink-web-client.git
synced 2025-01-03 23:07:26 +03:00
Improved styles by using Cards
This commit is contained in:
parent
d97cbdde5d
commit
1b97877ecf
2 changed files with 83 additions and 49 deletions
|
@ -5,6 +5,8 @@ import { pick } from 'ramda';
|
||||||
import { Card, CardBody, CardHeader } from 'reactstrap';
|
import { Card, CardBody, CardHeader } from 'reactstrap';
|
||||||
import { getShortUrlVisits } from './reducers/shortUrlVisits';
|
import { getShortUrlVisits } from './reducers/shortUrlVisits';
|
||||||
import VisitsParser from '../visits/services/VisitsParser';
|
import VisitsParser from '../visits/services/VisitsParser';
|
||||||
|
import preloader from '@fortawesome/fontawesome-free-solid/faCircleNotch';
|
||||||
|
import FontAwesomeIcon from '@fortawesome/react-fontawesome';
|
||||||
|
|
||||||
export class ShortUrlsVisits extends React.Component {
|
export class ShortUrlsVisits extends React.Component {
|
||||||
state = { startDate: '', endDate: '' };
|
state = { startDate: '', endDate: '' };
|
||||||
|
@ -15,14 +17,73 @@ export class ShortUrlsVisits extends React.Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { match: { params }, selectedServer, visitsParser, shortUrlVisits } = this.props;
|
const { match: { params }, selectedServer, visitsParser, shortUrlVisits: { visits, loading, error } } = this.props;
|
||||||
const serverUrl = selectedServer ? selectedServer.url : '';
|
const serverUrl = selectedServer ? selectedServer.url : '';
|
||||||
const shortUrl = `${serverUrl}/${params.shortCode}`;
|
const shortUrl = `${serverUrl}/${params.shortCode}`;
|
||||||
const generateGraphData = stats => ({
|
const generateGraphData = stats => ({
|
||||||
labels: Object.keys(stats),
|
labels: Object.keys(stats),
|
||||||
datasets: Object.values(stats)
|
data: Object.values(stats)
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const renderContent = () => {
|
||||||
|
if (loading) {
|
||||||
|
return (
|
||||||
|
<div className="col-md-10 offset-md-1">
|
||||||
|
<Card className="bg-light mt-4" body>
|
||||||
|
<h3 className="text-center text-muted">
|
||||||
|
<FontAwesomeIcon icon={preloader} spin /> Loading...
|
||||||
|
</h3>
|
||||||
|
</Card>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (error) {
|
||||||
|
return (
|
||||||
|
<Card className="mt-4" body inverse color="danger">
|
||||||
|
An error occurred while loading visits :(
|
||||||
|
</Card>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="row">
|
||||||
|
<div className="col-md-6">
|
||||||
|
<Card className="mt-4">
|
||||||
|
<CardHeader>Operating systems</CardHeader>
|
||||||
|
<CardBody>
|
||||||
|
<Doughnut data={generateGraphData(visitsParser.processOsStats(visits))} />
|
||||||
|
</CardBody>
|
||||||
|
</Card>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-6">
|
||||||
|
<Card className="mt-4">
|
||||||
|
<CardHeader>Browsers</CardHeader>
|
||||||
|
<CardBody>
|
||||||
|
<Doughnut data={generateGraphData(visitsParser.processBrowserStats(visits))} />
|
||||||
|
</CardBody>
|
||||||
|
</Card>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-6">
|
||||||
|
<Card className="mt-4">
|
||||||
|
<CardHeader>Countries</CardHeader>
|
||||||
|
<CardBody>
|
||||||
|
<HorizontalBar data={generateGraphData(visitsParser.processCountriesStats(visits))} />
|
||||||
|
</CardBody>
|
||||||
|
</Card>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-6">
|
||||||
|
<Card className="mt-4">
|
||||||
|
<CardHeader>Referrers</CardHeader>
|
||||||
|
<CardBody>
|
||||||
|
<HorizontalBar data={generateGraphData(visitsParser.processReferrersStats(visits))} />
|
||||||
|
</CardBody>
|
||||||
|
</Card>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="short-urls-container">
|
<div className="short-urls-container">
|
||||||
<Card className="bg-light">
|
<Card className="bg-light">
|
||||||
|
@ -31,40 +92,7 @@ export class ShortUrlsVisits extends React.Component {
|
||||||
</CardBody>
|
</CardBody>
|
||||||
</Card>
|
</Card>
|
||||||
|
|
||||||
<div className="row">
|
{renderContent()}
|
||||||
<div className="col-md-6">
|
|
||||||
<Card className="mt-4">
|
|
||||||
<CardHeader>Operating systems</CardHeader>
|
|
||||||
<CardBody>
|
|
||||||
<Doughnut data={generateGraphData(visitsParser.processOsStats(shortUrlVisits))} />
|
|
||||||
</CardBody>
|
|
||||||
</Card>
|
|
||||||
</div>
|
|
||||||
<div className="col-md-6">
|
|
||||||
<Card className="mt-4">
|
|
||||||
<CardHeader>Browsers</CardHeader>
|
|
||||||
<CardBody>
|
|
||||||
<Doughnut data={generateGraphData(visitsParser.processBrowserStats(shortUrlVisits))} />
|
|
||||||
</CardBody>
|
|
||||||
</Card>
|
|
||||||
</div>
|
|
||||||
<div className="col-md-6">
|
|
||||||
<Card className="mt-4">
|
|
||||||
<CardHeader>Countries</CardHeader>
|
|
||||||
<CardBody>
|
|
||||||
<HorizontalBar data={generateGraphData(visitsParser.processCountriesStats(shortUrlVisits))} />
|
|
||||||
</CardBody>
|
|
||||||
</Card>
|
|
||||||
</div>
|
|
||||||
<div className="col-md-6">
|
|
||||||
<Card className="mt-4">
|
|
||||||
<CardHeader>Referrers</CardHeader>
|
|
||||||
<CardBody>
|
|
||||||
<HorizontalBar data={generateGraphData(visitsParser.processReferrersStats(shortUrlVisits))} />
|
|
||||||
</CardBody>
|
|
||||||
</Card>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@ import { isNil } from 'ramda';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { CopyToClipboard } from 'react-copy-to-clipboard';
|
import { CopyToClipboard } from 'react-copy-to-clipboard';
|
||||||
import './CreateShortUrlResult.scss'
|
import './CreateShortUrlResult.scss'
|
||||||
import { Tooltip } from 'reactstrap';
|
import { Card, CardBody, Tooltip } from 'reactstrap';
|
||||||
|
|
||||||
export default class CreateShortUrlResult extends React.Component {
|
export default class CreateShortUrlResult extends React.Component {
|
||||||
state = { showCopyTooltip: false };
|
state = { showCopyTooltip: false };
|
||||||
|
@ -17,7 +17,11 @@ export default class CreateShortUrlResult extends React.Component {
|
||||||
const { error, result } = this.props;
|
const { error, result } = this.props;
|
||||||
|
|
||||||
if (error) {
|
if (error) {
|
||||||
return <div className="alert bg-danger text-white mt-3">An error occurred while creating the URL :(</div>
|
return (
|
||||||
|
<Card body color="danger" inverse className="bg-danger mt-3">
|
||||||
|
An error occurred while creating the URL :(
|
||||||
|
</Card>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
if (isNil(result)) {
|
if (isNil(result)) {
|
||||||
return null;
|
return null;
|
||||||
|
@ -30,19 +34,21 @@ export default class CreateShortUrlResult extends React.Component {
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="alert bg-main text-white mt-3">
|
<Card inverse className="bg-main mt-3">
|
||||||
<b>Great!</b> The short URL is <b>{shortUrl}</b>
|
<CardBody>
|
||||||
|
<b>Great!</b> The short URL is <b>{shortUrl}</b>
|
||||||
|
|
||||||
<CopyToClipboard text={shortUrl} onCopy={onCopy}>
|
<CopyToClipboard text={shortUrl} onCopy={onCopy}>
|
||||||
<button className="btn btn-light btn-sm create-short-url-result__copy-btn" id="copyBtn">
|
<button className="btn btn-light btn-sm create-short-url-result__copy-btn" id="copyBtn" type="button">
|
||||||
<FontAwesomeIcon icon={copyIcon}/> Copy
|
<FontAwesomeIcon icon={copyIcon}/> Copy
|
||||||
</button>
|
</button>
|
||||||
</CopyToClipboard>
|
</CopyToClipboard>
|
||||||
|
|
||||||
<Tooltip placement="left" isOpen={this.state.showCopyTooltip} target="copyBtn">
|
<Tooltip placement="left" isOpen={this.state.showCopyTooltip} target="copyBtn">
|
||||||
Copied!
|
Copied!
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
</div>
|
</CardBody>
|
||||||
|
</Card>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue