Fix showing incorrect stats
This commit is contained in:
parent
d618f89fb0
commit
2a53bf0921
|
@ -1,8 +1,8 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import subHours from 'date-fns/sub_hours';
|
import subHours from 'date-fns/subHours';
|
||||||
import subDays from 'date-fns/sub_days';
|
import subDays from 'date-fns/subDays';
|
||||||
import subMonths from 'date-fns/sub_months';
|
import subMonths from 'date-fns/subMonths';
|
||||||
import formatDate from 'date-fns/format';
|
import formatDate from 'date-fns/format';
|
||||||
import {
|
import {
|
||||||
AreaChart,
|
AreaChart,
|
||||||
|
@ -20,13 +20,13 @@ const ChartArea = ({ data: rawData, period }) => {
|
||||||
const getDate = index => {
|
const getDate = index => {
|
||||||
switch (period) {
|
switch (period) {
|
||||||
case 'allTime':
|
case 'allTime':
|
||||||
return formatDate(subMonths(now, rawData.length - index), 'MMM YY');
|
return formatDate(subMonths(now, rawData.length - index - 1), 'MMM yyy');
|
||||||
case 'lastDay':
|
case 'lastDay':
|
||||||
return formatDate(subHours(now, rawData.length - index), 'HH:00');
|
return formatDate(subHours(now, rawData.length - index - 1), 'HH:00');
|
||||||
case 'lastMonth':
|
case 'lastMonth':
|
||||||
case 'lastWeek':
|
case 'lastWeek':
|
||||||
default:
|
default:
|
||||||
return formatDate(subDays(now, rawData.length - index), 'MMM DD');
|
return formatDate(subDays(now, rawData.length - index - 1), 'MMM dd');
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
const data = rawData.map((view, index) => ({
|
const data = rawData.map((view, index) => ({
|
||||||
|
|
|
@ -45,13 +45,13 @@ const StatsCharts = ({ stats, period, updatedAt }) => {
|
||||||
const periodText = period.includes('last')
|
const periodText = period.includes('last')
|
||||||
? `the last ${period.replace('last', '').toLocaleLowerCase()}`
|
? `the last ${period.replace('last', '').toLocaleLowerCase()}`
|
||||||
: 'all time';
|
: 'all time';
|
||||||
const hasView = stats.views.filter(view => view > 0);
|
const hasView = stats.views.some(view => view > 0);
|
||||||
return (
|
return (
|
||||||
<ChartsWrapper>
|
<ChartsWrapper>
|
||||||
<Row>
|
<Row>
|
||||||
<Area data={stats.views} period={period} updatedAt={updatedAt} periodText={periodText} />
|
<Area data={stats.views} period={period} updatedAt={updatedAt} periodText={periodText} />
|
||||||
</Row>
|
</Row>
|
||||||
{hasView.length
|
{hasView
|
||||||
? [
|
? [
|
||||||
<Row key="second-row">
|
<Row key="second-row">
|
||||||
<Pie data={stats.stats.referrer} updatedAt={updatedAt} title="Referrals" />
|
<Pie data={stats.stats.referrer} updatedAt={updatedAt} title="Referrals" />
|
||||||
|
|
|
@ -49,7 +49,7 @@ const withTitle = ChartComponent => {
|
||||||
{props.periodText ? ` tracked clicks in ${props.periodText}` : props.title}.
|
{props.periodText ? ` tracked clicks in ${props.periodText}` : props.title}.
|
||||||
</Title>
|
</Title>
|
||||||
{props.periodText && props.updatedAt && (
|
{props.periodText && props.updatedAt && (
|
||||||
<SubTitle>Last update in {formatDate(props.updatedAt, 'dddd, hh:mm aa')}.</SubTitle>
|
<SubTitle>Last update in {formatDate(new Date(props.updatedAt), 'dddd, hh:mm aa')}.</SubTitle>
|
||||||
)}
|
)}
|
||||||
<ChartComponent {...props} />
|
<ChartComponent {...props} />
|
||||||
</Wrapper>
|
</Wrapper>
|
||||||
|
|
|
@ -2,7 +2,7 @@ import React from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import styled, { css } from 'styled-components';
|
import styled, { css } from 'styled-components';
|
||||||
import distanceInWordsToNow from 'date-fns/distance_in_words_to_now';
|
import distanceInWordsToNow from 'date-fns/formatDistanceToNow';
|
||||||
import TBodyShortUrl from './TBodyShortUrl';
|
import TBodyShortUrl from './TBodyShortUrl';
|
||||||
import TBodyCount from './TBodyCount';
|
import TBodyCount from './TBodyCount';
|
||||||
|
|
||||||
|
@ -93,7 +93,7 @@ const TableBody = ({ copiedIndex, handleCopy, tableLoading, showModal, urls }) =
|
||||||
<a href={url.target}>{url.target}</a>
|
<a href={url.target}>{url.target}</a>
|
||||||
</Td>
|
</Td>
|
||||||
<Td flex="1" date>
|
<Td flex="1" date>
|
||||||
{`${distanceInWordsToNow(url.created_at)} ago`}
|
{`${distanceInWordsToNow(new Date(url.created_at))} ago`}
|
||||||
</Td>
|
</Td>
|
||||||
<Td flex="1" withFade>
|
<Td flex="1" withFade>
|
||||||
<TBodyShortUrl index={index} copiedIndex={copiedIndex} handleCopy={handleCopy} url={url} />
|
<TBodyShortUrl index={index} copiedIndex={copiedIndex} handleCopy={handleCopy} url={url} />
|
||||||
|
|
|
@ -128,7 +128,6 @@ class TableOptions extends Component {
|
||||||
return (e) => {
|
return (e) => {
|
||||||
const { active } = e.target.dataset;
|
const { active } = e.target.dataset;
|
||||||
if (active === 'false') return null;
|
if (active === 'false') return null;
|
||||||
console.log({ page: this.props.url.page, num });
|
|
||||||
return this.props.getUrlsList({ page: this.props.url.page + num });
|
return this.props.getUrlsList({ page: this.props.url.page + num });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@ import Footer from '../components/Footer';
|
||||||
import { authUser } from '../actions';
|
import { authUser } from '../actions';
|
||||||
import Settings from '../components/Settings';
|
import Settings from '../components/Settings';
|
||||||
|
|
||||||
const SettingsPage = ({ auth, isAuthenticated }) => console.log({auth}) || (
|
const SettingsPage = ({ auth, isAuthenticated }) => (
|
||||||
<BodyWrapper>
|
<BodyWrapper>
|
||||||
{isAuthenticated ? <Settings /> : <PageLoading />}
|
{isAuthenticated ? <Settings /> : <PageLoading />}
|
||||||
<Footer />
|
<Footer />
|
||||||
|
|
|
@ -128,7 +128,7 @@ export const cooldownCheck = async (user: User) => {
|
||||||
throw new Error("Too much malware requests. You are now banned.");
|
throw new Error("Too much malware requests. You are now banned.");
|
||||||
}
|
}
|
||||||
const hasCooldownNow = user.cooldowns.some(cooldown =>
|
const hasCooldownNow = user.cooldowns.some(cooldown =>
|
||||||
isAfter(subHours(new Date(), 12), cooldown)
|
isAfter(subHours(new Date(), 12), new Date(cooldown))
|
||||||
);
|
);
|
||||||
if (hasCooldownNow) {
|
if (hasCooldownNow) {
|
||||||
throw new Error("Cooldown because of a malware URL. Wait 12h");
|
throw new Error("Cooldown because of a malware URL. Wait 12h");
|
||||||
|
@ -142,7 +142,7 @@ export const ipCooldownCheck: RequestHandler = async (req, res, next) => {
|
||||||
const ip = await getIP(req.realIP);
|
const ip = await getIP(req.realIP);
|
||||||
if (ip) {
|
if (ip) {
|
||||||
const timeToWait =
|
const timeToWait =
|
||||||
cooldownConfig - differenceInMinutes(new Date(), ip.created_at);
|
cooldownConfig - differenceInMinutes(new Date(), new Date(ip.created_at));
|
||||||
return res.status(400).json({
|
return res.status(400).json({
|
||||||
error:
|
error:
|
||||||
`Non-logged in users are limited. Wait ${timeToWait} ` +
|
`Non-logged in users are limited. Wait ${timeToWait} ` +
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import subMinutes from "date-fns/sub_minutes";
|
import { subMinutes } from "date-fns";
|
||||||
|
|
||||||
import knex from "../knex";
|
import knex from "../knex";
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import bcrypt from "bcryptjs";
|
import bcrypt from "bcryptjs";
|
||||||
import { isAfter, subDays } from "date-fns";
|
import { isAfter, subDays, set } from "date-fns";
|
||||||
import knex from "../knex";
|
import knex from "../knex";
|
||||||
import * as redis from "../redis";
|
import * as redis from "../redis";
|
||||||
import {
|
import {
|
||||||
|
@ -340,7 +340,10 @@ export const getStats = async (link: Link, domain: Domain) => {
|
||||||
|
|
||||||
for await (const visit of visitsStream as Visit[]) {
|
for await (const visit of visitsStream as Visit[]) {
|
||||||
STATS_PERIODS.forEach(([days, type]) => {
|
STATS_PERIODS.forEach(([days, type]) => {
|
||||||
const isIncluded = isAfter(visit.created_at, subDays(nowUTC, days));
|
const isIncluded = isAfter(
|
||||||
|
new Date(visit.created_at),
|
||||||
|
subDays(nowUTC, days)
|
||||||
|
);
|
||||||
if (isIncluded) {
|
if (isIncluded) {
|
||||||
const diffFunction = getDifferenceFunction(type);
|
const diffFunction = getDifferenceFunction(type);
|
||||||
const diff = diffFunction(now, visit.created_at);
|
const diff = diffFunction(now, visit.created_at);
|
||||||
|
@ -392,7 +395,11 @@ export const getStats = async (link: Link, domain: Domain) => {
|
||||||
|
|
||||||
const allTime = stats.allTime.stats;
|
const allTime = stats.allTime.stats;
|
||||||
const diffFunction = getDifferenceFunction("allTime");
|
const diffFunction = getDifferenceFunction("allTime");
|
||||||
const diff = diffFunction(now, visit.created_at);
|
const diff = diffFunction(
|
||||||
|
set(new Date(), { date: 1 }),
|
||||||
|
set(new Date(visit.created_at), { date: 1 })
|
||||||
|
);
|
||||||
|
console.log(diff);
|
||||||
const index = stats.allTime.views.length - diff - 1;
|
const index = stats.allTime.views.length - diff - 1;
|
||||||
const view = stats.allTime.views[index];
|
const view = stats.allTime.views[index];
|
||||||
stats.allTime.stats = {
|
stats.allTime.stats = {
|
||||||
|
@ -448,8 +455,8 @@ export const getStats = async (link: Link, domain: Domain) => {
|
||||||
views: stats.lastDay.views
|
views: stats.lastDay.views
|
||||||
},
|
},
|
||||||
lastMonth: {
|
lastMonth: {
|
||||||
stats: statsObjectToArray(stats.lastDay.stats),
|
stats: statsObjectToArray(stats.lastMonth.stats),
|
||||||
views: stats.lastDay.views
|
views: stats.lastMonth.views
|
||||||
},
|
},
|
||||||
lastWeek: {
|
lastWeek: {
|
||||||
stats: statsObjectToArray(stats.lastWeek.stats),
|
stats: statsObjectToArray(stats.lastWeek.stats),
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import bcrypt from "bcryptjs";
|
import bcrypt from "bcryptjs";
|
||||||
import nanoid from "nanoid";
|
import nanoid from "nanoid";
|
||||||
import uuid from "uuid/v4";
|
import uuid from "uuid/v4";
|
||||||
import addMinutes from "date-fns/add_minutes";
|
import { addMinutes } from "date-fns";
|
||||||
|
|
||||||
import knex from "../knex";
|
import knex from "../knex";
|
||||||
import * as redis from "../redis";
|
import * as redis from "../redis";
|
||||||
|
|
Loading…
Reference in New Issue