added comp_systems and modular instances frontend
This commit is contained in:
@@ -36,27 +36,48 @@ function ExperimentsListCard(props: {
|
||||
<Text mb="sm" size="md">
|
||||
Команда: {props.team?.team_name}
|
||||
</Text>
|
||||
<Pill className="ExperimentPill">
|
||||
<Text size="md">Статус: {props.experiment.experiment_status}</Text>
|
||||
</Pill>
|
||||
<div style={{ display: "flex", gap: "10px" }}>
|
||||
<Text size="md">Статус: </Text>
|
||||
<Pill style={{ backgroundColor: "var(--mantine-color-yellow-5)" }}>
|
||||
<Text size="md">{props.experiment.experiment_status}</Text>
|
||||
</Pill>
|
||||
</div>
|
||||
</div>
|
||||
<div className="ExperimentSectionWithLine">
|
||||
<SimpleGrid cols={2} verticalSpacing="0px">
|
||||
<Text>Задачи:</Text>
|
||||
{experiment_tasks.map((task: TaskData<any>) => {
|
||||
return (
|
||||
<Text
|
||||
size="md"
|
||||
style={{
|
||||
textWrap: "nowrap",
|
||||
textOverflow: "ellipsis",
|
||||
overflow: "hidden",
|
||||
}}
|
||||
>
|
||||
{task.name}
|
||||
</Text>
|
||||
);
|
||||
})}
|
||||
|
||||
{experiment_tasks.map(
|
||||
(
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
task: TaskData<any>,
|
||||
) => {
|
||||
return (
|
||||
<Pill
|
||||
size="md"
|
||||
style={{
|
||||
backgroundColor: "transparent",
|
||||
border: "2px solid black",
|
||||
alignContent: "center",
|
||||
alignItems: "center",
|
||||
justifyContent: "center",
|
||||
justifyItems: "center",
|
||||
}}
|
||||
>
|
||||
<Text
|
||||
size="md"
|
||||
style={{
|
||||
textWrap: "nowrap",
|
||||
textOverflow: "ellipsis",
|
||||
overflow: "hidden",
|
||||
}}
|
||||
>
|
||||
{task.name}
|
||||
</Text>
|
||||
</Pill>
|
||||
);
|
||||
},
|
||||
)}
|
||||
{experiment_tasks.length == 0 ? (
|
||||
<Pill size="md" className="ExperimentPill2">
|
||||
Нет Задач
|
||||
@@ -70,10 +91,14 @@ function ExperimentsListCard(props: {
|
||||
<div className="TopRightContainer">
|
||||
<div className="dateContainer">
|
||||
<Text size="sm">
|
||||
{props.experiment.date_created.toLocaleDateString("ru")}{" "}
|
||||
{new Date(
|
||||
props.experiment.date_created + "Z",
|
||||
).toLocaleDateString("ru")}{" "}
|
||||
</Text>
|
||||
<Text size="sm">
|
||||
{props.experiment.date_created.toLocaleTimeString("ru")}
|
||||
{new Date(
|
||||
props.experiment.date_created + "Z",
|
||||
).toLocaleTimeString("ru")}
|
||||
</Text>
|
||||
</div>
|
||||
<UnstyledButton
|
||||
|
||||
56
src/Components/ListCard/MachineListCard/MachinesListCard.css
Normal file
56
src/Components/ListCard/MachineListCard/MachinesListCard.css
Normal file
@@ -0,0 +1,56 @@
|
||||
.MachinesListCard {
|
||||
height: 85px;
|
||||
padding: 12px;
|
||||
}
|
||||
|
||||
.MachineSection {
|
||||
border-right: 1px solid var(--mantine-color-contrast-filled);
|
||||
padding-right: 10px;
|
||||
}
|
||||
|
||||
.MachinePill {
|
||||
background-color: var(--mantine-color-contrast-filled);
|
||||
color: var(--mantine-color-primary-filled);
|
||||
}
|
||||
|
||||
.MachinePill2 {
|
||||
border: 2px solid var(--mantine-color-accent-filled);
|
||||
background-color: transparent;
|
||||
color: var(--mantine-color-accent-filled);
|
||||
* {
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
||||
.membersPills {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.dateContainer {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: wrap;
|
||||
justify-content: right;
|
||||
gap: 5px;
|
||||
.p {
|
||||
text-wrap: nowrap;
|
||||
}
|
||||
}
|
||||
.TopRightContainer {
|
||||
justify-content: right;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: nowrap;
|
||||
gap: 15px;
|
||||
justify-items: center;
|
||||
}
|
||||
|
||||
.RightMachineSection {
|
||||
text-align: right;
|
||||
padding-right: 10px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
193
src/Components/ListCard/MachineListCard/MachinesListCard.tsx
Normal file
193
src/Components/ListCard/MachineListCard/MachinesListCard.tsx
Normal file
@@ -0,0 +1,193 @@
|
||||
import { Card, Pill, Text, UnstyledButton } from "@mantine/core";
|
||||
import "./MachinesListCard.css";
|
||||
import { useNavigate } from "react-router";
|
||||
import { IconCancel, IconCheck, IconTrash } from "@tabler/icons-react";
|
||||
import type { MouseEvent } from "react";
|
||||
import { notifications } from "@mantine/notifications";
|
||||
import { useDeviceStore } from "Stores/DeviceStore";
|
||||
import { deleteComputationalSystem } from "Api/QuantumBackend/MachineManagment";
|
||||
import type { SystemWithTeams } from "Types/Machine/Machine";
|
||||
|
||||
const colors = {
|
||||
ONLINE: "var(--mantine-color-green-7)",
|
||||
OFFLINE: "var(--mantine-color-red-7)",
|
||||
BUSY: "var(--mantine-color-yellow-5)",
|
||||
};
|
||||
|
||||
function MachinesListCard(props: SystemWithTeams) {
|
||||
const navigate = useNavigate();
|
||||
const { setTotalDevices, totalDevices, removeDevice } = useDeviceStore();
|
||||
|
||||
const handleDelete = () => {
|
||||
// TODO: fix delete
|
||||
deleteComputationalSystem({ system_id: props.system.id })
|
||||
.then(() => {
|
||||
removeDevice(props.system.id);
|
||||
setTotalDevices(totalDevices - 1);
|
||||
notifications.show({
|
||||
radius: "md",
|
||||
title: "Устройство удалено успешно",
|
||||
message: "",
|
||||
icon: <IconCheck />,
|
||||
style: { paddingLeft: "5px" },
|
||||
});
|
||||
})
|
||||
.catch(() => {
|
||||
notifications.show({
|
||||
radius: "md",
|
||||
color: "red",
|
||||
title: "Не удалось удалить устройство",
|
||||
message: "",
|
||||
icon: <IconCancel />,
|
||||
style: { paddingLeft: "5px" },
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<Card
|
||||
className="MachinesListCard"
|
||||
onClick={() => {
|
||||
navigate(props.system.id.toString());
|
||||
}}
|
||||
orientation="horizontal"
|
||||
>
|
||||
<Card.Section inheritPadding pl="sm" pr="xl">
|
||||
<Text mb="sm" size="md" style={{ textDecorationLine: "underline" }}>
|
||||
Устройство: {props.system.system_name}
|
||||
</Text>
|
||||
<div style={{ display: "flex" }}>
|
||||
<Text mb="sm" size="md">
|
||||
Статус:
|
||||
</Text>
|
||||
<Pill
|
||||
//className="MachinePill"
|
||||
style={{
|
||||
marginLeft: "10px",
|
||||
backgroundColor: colors[props.system.status || "ONLINE"],
|
||||
}}
|
||||
>
|
||||
<Text size="md">{props.system.status}</Text>
|
||||
</Pill>
|
||||
</div>
|
||||
</Card.Section>
|
||||
<Card.Section
|
||||
withBorder
|
||||
inheritPadding
|
||||
px="xs"
|
||||
style={{ textAlign: "right" }}
|
||||
>
|
||||
<Text mb="sm" size="md">
|
||||
Дата обновления статуса:
|
||||
</Text>
|
||||
<div style={{ display: "flex", gap: "10px", justifyContent: "right" }}>
|
||||
<Text size="sm">
|
||||
{new Date(props.system.created_at + "Z").toLocaleDateString(
|
||||
"ru",
|
||||
)}{" "}
|
||||
</Text>
|
||||
<Text size="sm">
|
||||
{new Date(props.system.created_at + "Z").toLocaleTimeString("ru")}
|
||||
</Text>
|
||||
</div>
|
||||
</Card.Section>
|
||||
<Card.Section
|
||||
inheritPadding
|
||||
px="xs"
|
||||
withBorder
|
||||
style={{
|
||||
flexGrow: "1",
|
||||
gap: "15px",
|
||||
display: "flex",
|
||||
flexDirection: "row",
|
||||
flexWrap: "wrap",
|
||||
}}
|
||||
>
|
||||
<Text>Команды с доступом:</Text>
|
||||
<div
|
||||
className="membersPills"
|
||||
style={{
|
||||
display: "flex",
|
||||
flexDirection: "row",
|
||||
flexWrap: "wrap",
|
||||
}}
|
||||
>
|
||||
{props.teams.map((team) => {
|
||||
return (
|
||||
<Pill className="MachinePill" style={{ marginLeft: "10px" }}>
|
||||
<Text
|
||||
size="md"
|
||||
style={{
|
||||
textWrap: "nowrap",
|
||||
textOverflow: "ellipsis",
|
||||
overflow: "hidden",
|
||||
}}
|
||||
>
|
||||
{team.team.team_name}
|
||||
</Text>
|
||||
</Pill>
|
||||
);
|
||||
})}
|
||||
{props.teams.length == 0 && (
|
||||
<Pill className="MachinePill2" style={{ marginLeft: "10px" }}>
|
||||
<Text
|
||||
size="md"
|
||||
style={{
|
||||
textWrap: "nowrap",
|
||||
textOverflow: "ellipsis",
|
||||
overflow: "hidden",
|
||||
}}
|
||||
>
|
||||
Команд нет
|
||||
</Text>
|
||||
</Pill>
|
||||
)}
|
||||
</div>
|
||||
</Card.Section>
|
||||
<Card.Section
|
||||
inheritPadding
|
||||
px="md"
|
||||
style={{
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
justifyContent: "space-between",
|
||||
}}
|
||||
>
|
||||
<div className="TopRightContainer">
|
||||
<div className="dateContainer">
|
||||
<Text size="sm">
|
||||
{new Date(props.system.created_at + "Z").toLocaleDateString(
|
||||
"ru",
|
||||
)}{" "}
|
||||
</Text>
|
||||
<Text size="sm">
|
||||
{new Date(props.system.created_at + "Z").toLocaleTimeString("ru")}
|
||||
</Text>
|
||||
</div>
|
||||
<UnstyledButton
|
||||
onClick={(e: MouseEvent) => {
|
||||
e.stopPropagation();
|
||||
handleDelete();
|
||||
}}
|
||||
style={{ cursor: "pointer" }}
|
||||
>
|
||||
<IconTrash size={20} />
|
||||
</UnstyledButton>
|
||||
</div>
|
||||
<div className="TopRightContainer">
|
||||
<div className="dateContainer">
|
||||
<Text size="sm">Максимальное количество кубит:</Text>
|
||||
<Text size="sm" style={{ fontWeight: "bold" }}>
|
||||
{props.system.max_qubits}
|
||||
</Text>
|
||||
</div>
|
||||
<Text c="dimmed" size="sm" style={{ alignSelf: "flex-end" }}>
|
||||
#{props.system.id}
|
||||
</Text>
|
||||
</div>
|
||||
</Card.Section>
|
||||
</Card>
|
||||
);
|
||||
}
|
||||
|
||||
export default MachinesListCard;
|
||||
@@ -0,0 +1,136 @@
|
||||
import { Card, Pill, Text, UnstyledButton } from "@mantine/core";
|
||||
import { useNavigate } from "react-router";
|
||||
import { IconCancel, IconCheck, IconTrash } from "@tabler/icons-react";
|
||||
import type { MouseEvent } from "react";
|
||||
import { notifications } from "@mantine/notifications";
|
||||
import { useDeviceStore } from "Stores/DeviceStore";
|
||||
import { removeSystemFromTeam } from "Api/QuantumBackend/MachineManagment";
|
||||
import type { SystemWithTeams } from "Types/Machine/Machine";
|
||||
|
||||
function TeamMachinesListCard(props: SystemWithTeams) {
|
||||
const navigate = useNavigate();
|
||||
const { setTotalDevices, totalDevices, removeDevice } = useDeviceStore();
|
||||
|
||||
const handleLeave = () => {
|
||||
// TODO: fix delete
|
||||
if (props.system) {
|
||||
removeSystemFromTeam({
|
||||
team_id: props.teams[0].team.team_id,
|
||||
system_id: props.system.id,
|
||||
})
|
||||
.then(() => {
|
||||
removeDevice(props.teams[0].team.team_id);
|
||||
setTotalDevices(totalDevices - 1);
|
||||
notifications.show({
|
||||
radius: "md",
|
||||
title: "Устройство удалено успешно",
|
||||
message: "",
|
||||
icon: <IconCheck />,
|
||||
style: { paddingLeft: "5px" },
|
||||
});
|
||||
})
|
||||
.catch(() => {
|
||||
notifications.show({
|
||||
radius: "md",
|
||||
color: "red",
|
||||
title: "Не удалось удалить устройство",
|
||||
message: "",
|
||||
icon: <IconCancel />,
|
||||
style: { paddingLeft: "5px" },
|
||||
});
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<Card
|
||||
onClick={() => {
|
||||
navigate(props.system.id.toString());
|
||||
}}
|
||||
orientation="horizontal"
|
||||
>
|
||||
<Card.Section
|
||||
inheritPadding
|
||||
withBorder
|
||||
px="xs"
|
||||
style={{ width: "250px" }}
|
||||
>
|
||||
<Text mb="sm" size="md" style={{ textDecorationLine: "underline" }}>
|
||||
Устройство: {props.system.system_name}
|
||||
</Text>
|
||||
</Card.Section>
|
||||
<Card.Section
|
||||
inheritPadding
|
||||
withBorder
|
||||
style={{
|
||||
display: "flex",
|
||||
flexDirection: "row",
|
||||
justifyContent: "space-between",
|
||||
flexGrow: "1",
|
||||
}}
|
||||
px="xs"
|
||||
>
|
||||
<div style={{ display: "flex" }}>
|
||||
<Text mb="sm" size="md">
|
||||
Статус:
|
||||
</Text>
|
||||
<Pill className="MachinePill" style={{ marginLeft: "10px" }}>
|
||||
<Text size="md">{props.system.status}</Text>
|
||||
</Pill>
|
||||
</div>
|
||||
<div style={{ display: "flex", gap: "15px" }}>
|
||||
<Text mb="sm" size="md">
|
||||
Дата обновления статуса:
|
||||
</Text>
|
||||
<Text size="md">
|
||||
{new Date(props.system.created_at + "Z").toLocaleDateString(
|
||||
"ru",
|
||||
)}{" "}
|
||||
</Text>
|
||||
<Text size="md">
|
||||
{new Date(props.system.created_at + "Z").toLocaleTimeString("ru")}
|
||||
</Text>
|
||||
</div>
|
||||
</Card.Section>
|
||||
<Card.Section
|
||||
inheritPadding
|
||||
px="xs"
|
||||
withBorder
|
||||
style={{
|
||||
gap: "15px",
|
||||
display: "flex",
|
||||
flexDirection: "row",
|
||||
}}
|
||||
>
|
||||
<Text size="md">Максимальное количество кубит:</Text>
|
||||
<Text size="md" style={{ fontWeight: "bold" }}>
|
||||
{props.system.max_qubits}
|
||||
</Text>
|
||||
</Card.Section>
|
||||
<Card.Section
|
||||
inheritPadding
|
||||
px="md"
|
||||
style={{
|
||||
width: "50px",
|
||||
}}
|
||||
>
|
||||
<UnstyledButton
|
||||
onClick={(e: MouseEvent) => {
|
||||
e.stopPropagation();
|
||||
handleLeave();
|
||||
}}
|
||||
style={{ cursor: "pointer" }}
|
||||
>
|
||||
<IconTrash size={20} />
|
||||
</UnstyledButton>
|
||||
</Card.Section>
|
||||
<Card.Section inheritPadding px="md">
|
||||
<Text c="dimmed" size="md" style={{ width: "20px" }}>
|
||||
#{props.system.id}
|
||||
</Text>
|
||||
</Card.Section>
|
||||
</Card>
|
||||
);
|
||||
}
|
||||
|
||||
export default TeamMachinesListCard;
|
||||
@@ -0,0 +1,116 @@
|
||||
import { Card, Text, UnstyledButton } from "@mantine/core";
|
||||
import { IconCancel, IconCheck, IconTrash } from "@tabler/icons-react";
|
||||
import type { MouseEvent } from "react";
|
||||
import { notifications } from "@mantine/notifications";
|
||||
import type { SystemTeamData, SystemWithTeams } from "Types/Machine/Machine";
|
||||
import { removeSystemFromTeam } from "Api/QuantumBackend/MachineManagment";
|
||||
import { useDeviceStore } from "Stores/DeviceStore";
|
||||
|
||||
function TeamInMachineListCard(props: {
|
||||
team: SystemTeamData;
|
||||
system: SystemWithTeams;
|
||||
}) {
|
||||
const { updateDevice } = useDeviceStore();
|
||||
|
||||
const handleRemovePerm = () => {
|
||||
// TODO: fix delete
|
||||
removeSystemFromTeam({
|
||||
team_id: props.team.team.team_id,
|
||||
system_id: props.system.system.id,
|
||||
})
|
||||
.then(() => {
|
||||
updateDevice(props.system.system.id, {
|
||||
teams: props.system.teams.filter(
|
||||
(team) => team.team.team_id != props.team.team.team_id,
|
||||
),
|
||||
});
|
||||
notifications.show({
|
||||
radius: "md",
|
||||
title: "Команда удалена успешно",
|
||||
message: "",
|
||||
icon: <IconCheck />,
|
||||
style: { paddingLeft: "5px" },
|
||||
});
|
||||
})
|
||||
.catch(() => {
|
||||
notifications.show({
|
||||
radius: "md",
|
||||
color: "red",
|
||||
title: "Не удалось удалить команду",
|
||||
message: "",
|
||||
icon: <IconCancel />,
|
||||
style: { paddingLeft: "5px" },
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
return (
|
||||
<Card orientation="horizontal">
|
||||
<Card.Section
|
||||
withBorder
|
||||
inheritPadding
|
||||
px="xs"
|
||||
style={{
|
||||
width: "430px",
|
||||
display: "flex",
|
||||
flexDirection: "row",
|
||||
gap: "15px",
|
||||
}}
|
||||
>
|
||||
<Text size="md" style={{ textDecorationLine: "underline" }}>
|
||||
Команда: {props.team.team.team_name}
|
||||
</Text>
|
||||
|
||||
<Text c="dimmed" size="md">
|
||||
#{props.team.team.team_id}
|
||||
</Text>
|
||||
</Card.Section>
|
||||
<Card.Section
|
||||
inheritPadding
|
||||
px="xs"
|
||||
withBorder
|
||||
style={{
|
||||
flexGrow: "1",
|
||||
gap: "15px",
|
||||
display: "flex",
|
||||
flexDirection: "row",
|
||||
}}
|
||||
>
|
||||
<Text>Количество кубит: {props.team.num_qubits}</Text>
|
||||
</Card.Section>
|
||||
<Card.Section
|
||||
inheritPadding
|
||||
px="md"
|
||||
style={{
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
justifyContent: "space-between",
|
||||
}}
|
||||
>
|
||||
<div className="TopRightContainer">
|
||||
<div className="dateContainer">
|
||||
<Text size="sm">
|
||||
{new Date(props.team.created_at + "Z").toLocaleDateString(
|
||||
"ru",
|
||||
)}{" "}
|
||||
</Text>
|
||||
<Text size="sm">
|
||||
{new Date(props.team.created_at + "Z").toLocaleTimeString("ru")}
|
||||
</Text>
|
||||
</div>
|
||||
<UnstyledButton
|
||||
onClick={(e: MouseEvent) => {
|
||||
e.stopPropagation();
|
||||
handleRemovePerm();
|
||||
}}
|
||||
style={{ cursor: "pointer" }}
|
||||
>
|
||||
<IconTrash size={20} />
|
||||
</UnstyledButton>
|
||||
</div>
|
||||
</Card.Section>
|
||||
</Card>
|
||||
);
|
||||
}
|
||||
|
||||
export default TeamInMachineListCard;
|
||||
@@ -1,6 +1,3 @@
|
||||
.TeamMembers {
|
||||
margin-top: 10px;
|
||||
gap: 10px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
.TeamMemberCard {
|
||||
min-height: 100px;
|
||||
}
|
||||
|
||||
@@ -30,7 +30,13 @@ function TeamMemberCard(props: { cur_team: Team; member: TeamMember }) {
|
||||
);
|
||||
|
||||
return (
|
||||
<Card padding="sm" withBorder orientation="horizontal">
|
||||
<Card
|
||||
padding="sm"
|
||||
withBorder
|
||||
orientation="horizontal"
|
||||
className="TeamMemberCard"
|
||||
key={props.member.user.keycloak_id}
|
||||
>
|
||||
<Card.Section
|
||||
inheritPadding
|
||||
px="xs"
|
||||
@@ -168,7 +174,6 @@ function TeamMemberCard(props: { cur_team: Team; member: TeamMember }) {
|
||||
placeholder="Выберите разрешения"
|
||||
searchable
|
||||
data={props.cur_team.creator.permissions}
|
||||
classNames={{ input: "MantineInput" }}
|
||||
onChange={(value) => {
|
||||
set_selected_permissions(value);
|
||||
}}
|
||||
@@ -227,10 +232,10 @@ function TeamMemberCard(props: { cur_team: Team; member: TeamMember }) {
|
||||
}}
|
||||
>
|
||||
<Text size="sm" style={{ textAlign: "right" }}>
|
||||
{new Date(props.member.joined_at).toLocaleDateString("ru")}
|
||||
{new Date(props.member.joined_at + "Z").toLocaleDateString("ru")}
|
||||
</Text>
|
||||
<Text size="sm" style={{ textAlign: "right" }}>
|
||||
{new Date(props.member.joined_at).toLocaleTimeString("ru")}
|
||||
{new Date(props.member.joined_at + "Z").toLocaleTimeString("ru")}
|
||||
</Text>
|
||||
</div>
|
||||
</Stack>
|
||||
|
||||
@@ -90,17 +90,19 @@ function TeamsListCard(props: Team) {
|
||||
<Text mb="sm" size="md" style={{ textDecorationLine: "underline" }}>
|
||||
Команда: {props.name}
|
||||
</Text>
|
||||
<Text mb="sm" size="md">
|
||||
Владелец:
|
||||
<div style={{ display: "flex" }}>
|
||||
<Text mb="sm" size="md">
|
||||
Владелец:
|
||||
</Text>
|
||||
<Pill className="TeamPill" style={{ marginLeft: "10px" }}>
|
||||
<Text size="md">{props.creator.user.username}</Text>
|
||||
</Pill>
|
||||
</Text>
|
||||
</div>
|
||||
<div className="membersPills">
|
||||
<Text>Члены:</Text>
|
||||
{props.members.map((team: TeamMember) => {
|
||||
return (
|
||||
<Pill className="TeamPill" style={{ marginLeft: "10px" }}>
|
||||
<Pill className="TeamPill">
|
||||
<Text
|
||||
size="md"
|
||||
style={{
|
||||
@@ -170,10 +172,10 @@ function TeamsListCard(props: Team) {
|
||||
<div className="TopRightContainer">
|
||||
<div className="dateContainer">
|
||||
<Text size="sm">
|
||||
{new Date(props.created_at).toLocaleDateString()}{" "}
|
||||
{new Date(props.created_at + "Z").toLocaleDateString()}{" "}
|
||||
</Text>
|
||||
<Text size="sm">
|
||||
{new Date(props.created_at).toLocaleTimeString()}
|
||||
{new Date(props.created_at + "Z").toLocaleTimeString()}
|
||||
</Text>
|
||||
</div>
|
||||
{props.creator.user.keycloak_id == profile?.id && (
|
||||
|
||||
Reference in New Issue
Block a user