You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
bazarr/frontend/src/History/Statistics/index.tsx

132 lines
3.9 KiB

import { merge } from "lodash";
import React, { FunctionComponent, useCallback, useState } from "react";
import { Col, Container } from "react-bootstrap";
import { Helmet } from "react-helmet";
import {
Bar,
BarChart,
CartesianGrid,
Legend,
ResponsiveContainer,
Tooltip,
XAxis,
YAxis,
} from "recharts";
import { useLanguages, useProviders } from "../../@redux/hooks";
import { HistoryApi } from "../../apis";
import {
AsyncSelector,
ContentHeader,
LanguageSelector,
PromiseOverlay,
Selector,
} from "../../components";
import { useAutoUpdate } from "../../utilites/hooks";
import { actionOptions, timeframeOptions } from "./options";
function converter(item: History.Stat) {
const movies = item.movies.map((v) => ({
date: v.date,
movies: v.count,
}));
const series = item.series.map((v) => ({
date: v.date,
series: v.count,
}));
const result = merge(movies, series);
return result;
}
const providerLabel = (item: System.Provider) => item.name;
const SelectorContainer: FunctionComponent = ({ children }) => (
<Col xs={6} lg={3} className="p-1">
{children}
</Col>
);
const HistoryStats: FunctionComponent = () => {
const [languages] = useLanguages(true);
const [providerList, update] = useProviders();
useAutoUpdate(update);
const [timeframe, setTimeframe] = useState<History.TimeframeOptions>("month");
const [action, setAction] = useState<Nullable<History.ActionOptions>>(null);
const [lang, setLanguage] = useState<Nullable<Language>>(null);
const [provider, setProvider] = useState<Nullable<System.Provider>>(null);
const promise = useCallback(() => {
return HistoryApi.stats(
timeframe,
action ?? undefined,
provider?.name,
lang?.code2
);
}, [timeframe, lang?.code2, action, provider]);
return (
// TODO: Responsive
<Container fluid className="vh-75">
<Helmet>
<title>History Statistics - Bazarr</title>
</Helmet>
<PromiseOverlay promise={promise}>
{(data) => (
<React.Fragment>
<ContentHeader scroll={false}>
<SelectorContainer>
<Selector
placeholder="Time..."
options={timeframeOptions}
value={timeframe}
onChange={(v) => setTimeframe(v ?? "month")}
></Selector>
</SelectorContainer>
<SelectorContainer>
<Selector
placeholder="Action..."
clearable
options={actionOptions}
value={action}
onChange={setAction}
></Selector>
</SelectorContainer>
<SelectorContainer>
<AsyncSelector
placeholder="Provider..."
clearable
state={providerList}
label={providerLabel}
onChange={setProvider}
></AsyncSelector>
</SelectorContainer>
<SelectorContainer>
<LanguageSelector
clearable
options={languages}
value={lang}
onChange={setLanguage}
></LanguageSelector>
</SelectorContainer>
</ContentHeader>
<ResponsiveContainer height="100%">
<BarChart data={converter(data)}>
<CartesianGrid strokeDasharray="4 2"></CartesianGrid>
<XAxis dataKey="date"></XAxis>
<YAxis allowDecimals={false}></YAxis>
<Tooltip></Tooltip>
<Legend verticalAlign="top"></Legend>
<Bar name="Series" dataKey="series" fill="#2493B6"></Bar>
<Bar name="Movies" dataKey="movies" fill="#FFC22F"></Bar>
</BarChart>
</ResponsiveContainer>
</React.Fragment>
)}
</PromiseOverlay>
</Container>
);
};
export default HistoryStats;