Frontend updates with new stream group changes

This commit is contained in:
dekzter 2025-03-19 17:05:22 -04:00
parent 8cdf9a40cf
commit 19aa76e55d
3 changed files with 115 additions and 83 deletions

View file

@ -5,16 +5,18 @@ import * as Yup from 'yup';
import API from '../../api';
import useStreamProfilesStore from '../../store/streamProfiles';
import { Modal, TextInput, Select, Button, Flex } from '@mantine/core';
import useChannelsStore from '../../store/channels';
const Stream = ({ stream = null, isOpen, onClose }) => {
const streamProfiles = useStreamProfilesStore((state) => state.profiles);
const { channelGroups } = useChannelsStore();
const [selectedStreamProfile, setSelectedStreamProfile] = useState('');
const formik = useFormik({
initialValues: {
name: '',
url: '',
group_name: '',
channel_group: null,
stream_profile_id: '',
},
validationSchema: Yup.object({
@ -23,6 +25,7 @@ const Stream = ({ stream = null, isOpen, onClose }) => {
// stream_profile_id: Yup.string().required('Stream profile is required'),
}),
onSubmit: async (values, { setSubmitting, resetForm }) => {
console.log(values);
if (stream?.id) {
await API.updateStream({ id: stream.id, ...values });
} else {
@ -40,7 +43,7 @@ const Stream = ({ stream = null, isOpen, onClose }) => {
formik.setValues({
name: stream.name,
url: stream.url,
group_name: stream.group_name,
channel_group: stream.channel_group,
stream_profile_id: stream.stream_profile_id,
});
} else {
@ -73,13 +76,19 @@ const Stream = ({ stream = null, isOpen, onClose }) => {
error={formik.errors.url}
/>
<TextInput
id="group_name"
name="group_name"
<Select
id="channel_group"
name="channel_group"
label="Group"
value={formik.values.group_name}
onChange={formik.handleChange}
error={formik.errors.group_name}
value={formik.values.channel_group}
onChange={(value) => {
formik.setFieldValue('channel_group', value); // Update Formik's state with the new value
}}
error={formik.errors.channel_group}
data={channelGroups.map((group) => ({
label: group.name,
value: `${group.id}`,
}))}
/>
<Select
@ -87,8 +96,10 @@ const Stream = ({ stream = null, isOpen, onClose }) => {
name="stream_profile_id"
label="Stream Profile"
placeholder="Optional"
value={selectedStreamProfile}
onChange={setSelectedStreamProfile}
value={formik.values.stream_profile_id}
onChange={(value) => {
formik.setFieldValue('stream_profile_id', value); // Update Formik's state with the new value
}}
error={formik.errors.stream_profile_id}
data={streamProfiles.map((profile) => ({
label: profile.name,

View file

@ -71,7 +71,7 @@ const StreamsTable = ({}) => {
});
const [filters, setFilters] = useState({
name: '',
group_name: '',
channel_group: '',
m3u_account: '',
});
const debouncedFilters = useDebounce(filters, 500);
@ -83,7 +83,7 @@ const StreamsTable = ({}) => {
* Stores
*/
const { playlists } = usePlaylistsStore();
const { channelsPageSelection } = useChannelsStore();
const { channelGroups, channelsPageSelection } = useChannelsStore();
const channelSelectionStreams = useChannelsStore(
(state) => state.channels[state.channelsPageSelection[0]?.id]?.streams
);
@ -133,7 +133,8 @@ const StreamsTable = ({}) => {
},
{
header: 'Group',
accessorKey: 'group_name',
accessorFn: (row) =>
channelGroups.find((group) => group.id === row.channel_group)?.name,
size: 100,
Header: ({ column }) => (
<Box onClick={handleSelectClick}>
@ -200,7 +201,7 @@ const StreamsTable = ({}) => {
const handleGroupChange = (value) => {
setFilters((prev) => ({
...prev,
group_name: value ? value : '',
channel_group: value ? value : '',
}));
};

View file

@ -1,5 +1,18 @@
import React, { useMemo, useState, useEffect, useCallback } from 'react';
import { ActionIcon, Box, Center, Grid, Text } from '@mantine/core';
import {
ActionIcon,
Box,
Card,
Center,
Flex,
Grid,
Group,
SimpleGrid,
Stack,
Text,
Title,
Tooltip,
} from '@mantine/core';
import { MantineReactTable, useMantineReactTable } from 'mantine-react-table';
import { TableHelper } from '../helpers';
import API from '../api';
@ -15,7 +28,32 @@ import {
Binary,
ArrowDown01,
SquareX,
Timer,
} from 'lucide-react';
import dayjs from 'dayjs';
import duration from 'dayjs/plugin/duration';
import relativeTime from 'dayjs/plugin/relativeTime';
dayjs.extend(duration);
dayjs.extend(relativeTime);
const getStartDate = (uptime) => {
// Get the current date and time
const currentDate = new Date();
// Calculate the start date by subtracting uptime (in milliseconds)
const startDate = new Date(currentDate.getTime() - uptime * 1000);
// Format the date as a string (you can adjust the format as needed)
return startDate.toLocaleString({
weekday: 'short', // optional, adds day of the week
year: 'numeric',
month: '2-digit',
day: '2-digit',
hour: '2-digit',
minute: '2-digit',
second: '2-digit',
hour12: true, // 12-hour format with AM/PM
});
};
const ChannelsPage = () => {
const { channels, channelsByUUID, stats: channelStats } = useChannelsStore();
@ -146,32 +184,6 @@ const ChannelsPage = () => {
data: clients,
columns: useMemo(
() => [
{
id: 'logo',
header: 'Logo',
accessorKey: 'channel.logo_url',
size: 50,
Cell: ({ cell }) => (
<Center>
<img
src={cell.getValue() || logo}
width="20"
alt="channel logo"
/>
</Center>
),
},
{
header: 'Channel',
accessorKey: 'channel.name',
size: 100,
mantineTableBodyCellProps: {
style: {
whiteSpace: 'nowrap',
maxWidth: 100,
},
},
},
{
header: 'User-Agent',
accessorKey: 'user_agent',
@ -180,6 +192,8 @@ const ChannelsPage = () => {
style: {
whiteSpace: 'nowrap',
maxWidth: 400,
paddingLeft: 10,
paddingRight: 10,
},
},
},
@ -243,48 +257,54 @@ const ChannelsPage = () => {
}, [channelStats]);
return (
<Grid style={{ padding: 18 }}>
<Grid.Col span={6}>
<Text
w={88}
h={24}
style={{
fontFamily: 'Inter, sans-serif',
fontWeight: 500,
fontSize: '20px',
lineHeight: 1,
letterSpacing: '-0.3px',
color: 'gray.6', // Adjust this to match MUI's theme.palette.text.secondary
marginBottom: 0,
}}
>
Channels
</Text>
<Box style={{ paddingTop: 10 }}>
<MantineReactTable table={channelsTable} />
</Box>
</Grid.Col>
<Grid.Col span={6}>
<Text
w={88}
h={24}
style={{
fontFamily: 'Inter, sans-serif',
fontWeight: 500,
fontSize: '20px',
lineHeight: 1,
letterSpacing: '-0.3px',
color: 'gray.6', // Adjust this to match MUI's theme.palette.text.secondary
marginBottom: 0,
}}
>
Clients
</Text>
<Box style={{ paddingTop: 10 }}>
<MantineReactTable table={clientsTable} />
</Box>
</Grid.Col>
</Grid>
<SimpleGrid cols={2} spacing="md" style={{ padding: 10 }}>
{activeChannels.map((channel) => (
<Card shadow="sm" padding="lg" radius="md" withBorder>
<Stack>
<Flex justify="space-between" align="center">
<Group>
<Title order={5}>{channel.name}</Title>
<img
src={channel.logo_url || logo}
width="20"
alt="channel logo"
/>
</Group>
<Group>
<Box>
<Tooltip label={getStartDate(channel.uptime)}>
<Center>
<Timer style={{ paddingRight: 5 }} />
{dayjs.duration(channel.uptime, 'seconds').humanize()}
</Center>
</Tooltip>
</Box>
<Center>
<Tooltip label="Stop Channel">
<ActionIcon variant="transparent" color="red.9">
<SquareX size="24" />
</ActionIcon>
</Tooltip>
</Center>
</Group>
</Flex>
<Box>
<Flex
justify="space-between"
align="center"
style={{ paddingRight: 10, paddingLeft: 10 }}
>
<Text>Clients</Text>
<Text>{channel.client_count}</Text>
</Flex>
<MantineReactTable table={clientsTable} />
</Box>
</Stack>
</Card>
))}
</SimpleGrid>
);
};