tables
This commit is contained in:
@@ -1,4 +1,6 @@
|
|||||||
import React, { useState, useEffect } from 'react';
|
import React, { useState, useEffect } from 'react';
|
||||||
|
import { Table } from 'antd';
|
||||||
|
|
||||||
import { CONNECTED_CLIENTS, fetchData, FETCH_INTERVAL } from '../utils/apis';
|
import { CONNECTED_CLIENTS, fetchData, FETCH_INTERVAL } from '../utils/apis';
|
||||||
|
|
||||||
export default function HardwareInfo() {
|
export default function HardwareInfo() {
|
||||||
@@ -16,12 +18,10 @@ geo data looks like this
|
|||||||
const getInfo = async () => {
|
const getInfo = async () => {
|
||||||
try {
|
try {
|
||||||
const result = await fetchData(CONNECTED_CLIENTS);
|
const result = await fetchData(CONNECTED_CLIENTS);
|
||||||
console.log("================ result", result)
|
setClients(result);
|
||||||
|
|
||||||
setClients({ ...result });
|
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
setClients({ ...clients, message: error.message });
|
console.log("==== error", error)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -37,14 +37,45 @@ geo data looks like this
|
|||||||
}
|
}
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
const columns = [
|
||||||
|
{
|
||||||
|
title: 'User name',
|
||||||
|
dataIndex: 'username',
|
||||||
|
key: 'username',
|
||||||
|
render: username => username || '-',
|
||||||
|
sorter: (a, b) => a.username - b.username,
|
||||||
|
sortDirections: ['descend', 'ascend'],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Messages sent',
|
||||||
|
dataIndex: 'messageCount',
|
||||||
|
key: 'messageCount',
|
||||||
|
sorter: (a, b) => a.messageCount - b.messageCount,
|
||||||
|
sortDirections: ['descend', 'ascend'],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Connected Time',
|
||||||
|
dataIndex: 'connectedAt',
|
||||||
|
key: 'connectedAt',
|
||||||
|
render: time => (Date.now() - (new Date(time).getTime())) / 1000 / 60,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'User Agent',
|
||||||
|
dataIndex: 'userAgent',
|
||||||
|
key: 'userAgent',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Location',
|
||||||
|
dataIndex: 'geo',
|
||||||
|
key: 'geo',
|
||||||
|
render: geo => geo && `${geo.regionName}, ${geo.countryCode}`,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<h2>Connected Clients</h2>
|
<h2>Connected Clients</h2>
|
||||||
<p>a table of info..</p>
|
<Table dataSource={clients} columns={columns} />;
|
||||||
<p>who's watching, how long they've been there, have they chatted? where they from?</p>
|
|
||||||
<div style={{border: '1px solid purple', height: '300px', width: '100%', overflow:'auto'}}>
|
|
||||||
{JSON.stringify(clients)}
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ import {timeFormat} from 'd3-time-format';
|
|||||||
import { LineChart, XAxis, YAxis, Line, Tooltip } from 'recharts';
|
import { LineChart, XAxis, YAxis, Line, Tooltip } from 'recharts';
|
||||||
import { VIEWERS_OVER_TIME, fetchData } from '../utils/apis';
|
import { VIEWERS_OVER_TIME, fetchData } from '../utils/apis';
|
||||||
|
|
||||||
|
|
||||||
const FETCH_INTERVAL = 5 * 60 * 1000; // 5 mins
|
const FETCH_INTERVAL = 5 * 60 * 1000; // 5 mins
|
||||||
|
|
||||||
export default function ViewersOverTime() {
|
export default function ViewersOverTime() {
|
||||||
@@ -13,7 +12,6 @@ export default function ViewersOverTime() {
|
|||||||
try {
|
try {
|
||||||
const result = await fetchData(VIEWERS_OVER_TIME);
|
const result = await fetchData(VIEWERS_OVER_TIME);
|
||||||
setViewerInfo(result);
|
setViewerInfo(result);
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log("==== error", error)
|
console.log("==== error", error)
|
||||||
}
|
}
|
||||||
@@ -33,22 +31,41 @@ export default function ViewersOverTime() {
|
|||||||
|
|
||||||
const timeFormatter = (tick) => {return timeFormat('%H:%M:%S')(new Date(tick));};
|
const timeFormatter = (tick) => {return timeFormat('%H:%M:%S')(new Date(tick));};
|
||||||
|
|
||||||
|
const CustomizedTooltip = (props) => {
|
||||||
|
const { active, payload, label } = props;
|
||||||
|
if (active) {
|
||||||
|
const numViewers = payload && payload[0] && payload[0].value;
|
||||||
|
const time = timeFormatter(label);
|
||||||
|
const message = `${numViewers} viewer(s) at ${time}`;
|
||||||
|
return (
|
||||||
|
<div className="custom-tooltip">
|
||||||
|
<p className="label">{message}</p>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div style={{backgroundColor: '#333'}}>
|
<div>
|
||||||
<h2>Viewers over time</h2>
|
<h2>Current Viewers</h2>
|
||||||
<p>Time on X axis, # Viewer on Y</p>
|
<div className="chart-container">
|
||||||
<div style={{border: '1px solid red', height: '300px', width: '100%', overflow:'auto'}}>
|
|
||||||
{JSON.stringify(viewerInfo)}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<LineChart width={800} height={400} data={viewerInfo}>
|
<LineChart width={800} height={400} data={viewerInfo}>
|
||||||
<XAxis dataKey="time" tickFormatter={timeFormatter}/>
|
<XAxis dataKey="time" tickFormatter={timeFormatter}/>
|
||||||
<YAxis dataKey="value"/>
|
<YAxis dataKey="value"/>
|
||||||
<Tooltip cursor={{ stroke: 'red', strokeWidth: 2 }} />
|
<Tooltip
|
||||||
<Line type="monotone" dataKey="value" stroke="#ff84d8" dot={{ stroke: 'red', strokeWidth: 2 }} />
|
content={<CustomizedTooltip />}
|
||||||
|
/>
|
||||||
|
<Line
|
||||||
|
type="monotone"
|
||||||
|
dataKey="value"
|
||||||
|
stroke="#ff84d8"
|
||||||
|
dot={{ stroke: 'red', strokeWidth: 2 }}
|
||||||
|
/>
|
||||||
</LineChart>
|
</LineChart>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
import React, { useState, useEffect } from 'react';
|
import React, { useState, useEffect } from 'react';
|
||||||
|
import { Layout } from 'antd';
|
||||||
|
|
||||||
|
|
||||||
import BroadcastInfo from './components/broadcast-info';
|
import BroadcastInfo from './components/broadcast-info';
|
||||||
import HardwareInfo from './components/hardware-info';
|
import HardwareInfo from './components/hardware-info';
|
||||||
@@ -9,20 +11,32 @@ import ConnectedClients from './components/connected-clients';
|
|||||||
export default function HomeView(props) {
|
export default function HomeView(props) {
|
||||||
const { broadcastActive, broadcaster, message } = props;
|
const { broadcastActive, broadcaster, message } = props;
|
||||||
|
|
||||||
|
const { Header, Footer, Content } = Layout;
|
||||||
|
|
||||||
const broadcastDetails = broadcastActive ? (
|
const broadcastDetails = broadcastActive ? (
|
||||||
<>
|
<>
|
||||||
{/* <BroadcastInfo {...broadcaster} />
|
{/* <BroadcastInfo {...broadcaster} />
|
||||||
<HardwareInfo /> */}
|
<HardwareInfo /> */}
|
||||||
<ViewerInfo />
|
<ViewerInfo />
|
||||||
{/* <ConnectedClients />
|
<ConnectedClients />
|
||||||
<ServerConfig /> */}
|
{/* <ServerConfig /> */}
|
||||||
</>
|
</>
|
||||||
) : null;
|
) : null;
|
||||||
|
|
||||||
const disconnectButton = broadcastActive ? <button type="button">Boot (Disconnect)</button> : null;
|
const disconnectButton = broadcastActive ? <button type="button">Boot (Disconnect)</button> : null;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div style={{ padding: '2em' }}>
|
<Layout className="layout">
|
||||||
|
<Header>
|
||||||
|
<div className="logo">logo</div>
|
||||||
|
{/* <Menu theme="dark" mode="horizontal" defaultSelectedKeys={['2']}>
|
||||||
|
<Menu.Item key="1">nav 1</Menu.Item>
|
||||||
|
<Menu.Item key="2">nav 2</Menu.Item>
|
||||||
|
<Menu.Item key="3">nav 3</Menu.Item>
|
||||||
|
</Menu> */}
|
||||||
|
</Header>
|
||||||
|
<Content style={{ padding: '0 50px' }}>
|
||||||
|
<div className="site-layout-content">
|
||||||
<p>
|
<p>
|
||||||
<b>Status: {broadcastActive ? 'on' : 'off'}</b>
|
<b>Status: {broadcastActive ? 'on' : 'off'}</b>
|
||||||
</p>
|
</p>
|
||||||
@@ -38,6 +52,14 @@ export default function HomeView(props) {
|
|||||||
<br />
|
<br />
|
||||||
|
|
||||||
{broadcastDetails}
|
{broadcastDetails}
|
||||||
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
</Content>
|
||||||
|
<Footer style={{ textAlign: 'center' }}><a href="https://owncast.online/">About Owncast</a></Footer>
|
||||||
|
</Layout>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user