upd
This commit is contained in:
@@ -1,3 +1,5 @@
|
||||
# VITE_COORD_URL=http://localhost:4000
|
||||
VITE_COORD_URL=https://coord.graff.tech
|
||||
VITE_CRM_API_URL=https://crm.stream.graff.tech/api
|
||||
# VITE_CRM_API_URL=http://localhost:3001
|
||||
VITE_CRM_API_URL=http://192.168.1.170:3001
|
||||
# VITE_CRM_API_URL=https://crm.stream.graff.tech/api
|
||||
@@ -35,15 +35,13 @@ function MonitoringPage() {
|
||||
}
|
||||
|
||||
async function endSession(activeSessionId: string) {
|
||||
const result = await ky
|
||||
await ky
|
||||
.post(
|
||||
`${
|
||||
import.meta.env.VITE_COORD_URL
|
||||
}/active_sessions/${activeSessionId}/end`
|
||||
)
|
||||
.json();
|
||||
|
||||
console.log(result);
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
|
||||
+11
-18
@@ -3,24 +3,23 @@
|
||||
import ky from "ky";
|
||||
import { useEffect, useState } from "react";
|
||||
import Countdown from "react-countdown";
|
||||
import { useNavigate, useSearchParams } from "react-router-dom";
|
||||
import { useNavigate, useParams } from "react-router-dom";
|
||||
|
||||
function ScheduledPage() {
|
||||
const [searchParams] = useSearchParams();
|
||||
const params = useParams();
|
||||
// const [searchParams] = useSearchParams();
|
||||
const navigate = useNavigate();
|
||||
const [countdownSeconds, setCountdownSeconds] = useState<number>();
|
||||
|
||||
async function connect() {
|
||||
const userInviteKey = searchParams.get("userInviteKey");
|
||||
console.log(params.sessionId);
|
||||
|
||||
async function connect() {
|
||||
try {
|
||||
const result: any = await ky
|
||||
.get(
|
||||
`${
|
||||
import.meta.env.VITE_COORD_URL
|
||||
}/active_sessions/scheduled?userInviteKey=${userInviteKey}`
|
||||
)
|
||||
.json();
|
||||
const result: any = await ky.get(
|
||||
`${import.meta.env.VITE_CRM_API_URL}/scheduled_sessions/${
|
||||
params.sessionId
|
||||
}`
|
||||
);
|
||||
|
||||
if (!result.id) {
|
||||
setCountdownSeconds(result.countdownSeconds);
|
||||
@@ -36,13 +35,7 @@ function ScheduledPage() {
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
if (searchParams.get("userInviteKey")) {
|
||||
// console.log(searchParams.get("userInviteKey"));
|
||||
|
||||
connect();
|
||||
} else {
|
||||
navigate("/");
|
||||
}
|
||||
connect();
|
||||
}, []);
|
||||
|
||||
return (
|
||||
|
||||
@@ -81,8 +81,6 @@ function StreamPage() {
|
||||
const diffMs = differenceInMilliseconds(new Date(), date);
|
||||
setStopwatch(format(diffMs, "mm:ss"));
|
||||
|
||||
console.log();
|
||||
|
||||
setTimeout(() => {
|
||||
updateStartDate(date);
|
||||
}, 1000);
|
||||
|
||||
@@ -2,13 +2,10 @@
|
||||
/* eslint-disable react-hooks/exhaustive-deps */
|
||||
import {
|
||||
add,
|
||||
differenceInDays,
|
||||
eachDayOfInterval,
|
||||
endOfMonth,
|
||||
format,
|
||||
getDay,
|
||||
isAfter,
|
||||
isBefore,
|
||||
isEqual,
|
||||
isWithinInterval,
|
||||
parse,
|
||||
@@ -25,13 +22,14 @@ import i18n from "../i18n";
|
||||
interface CalendarProps {
|
||||
schedules: any[];
|
||||
handleSelect: (day: Date) => void;
|
||||
className?: string;
|
||||
}
|
||||
|
||||
function classNames(...classes: (string | boolean)[]) {
|
||||
return classes.filter(Boolean).join(" ");
|
||||
}
|
||||
|
||||
function Calendar({ schedules, handleSelect }: CalendarProps) {
|
||||
function Calendar({ schedules, handleSelect, className }: CalendarProps) {
|
||||
const today = startOfToday();
|
||||
const [selectedDay, setSelectedDay] = useState<Date | null>(null);
|
||||
const [currentMonth, setCurrentMonth] = useState(format(today, "MMM-yyyy"));
|
||||
@@ -53,15 +51,13 @@ function Calendar({ schedules, handleSelect }: CalendarProps) {
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
console.log(schedules);
|
||||
|
||||
if (!selectedDay) return;
|
||||
|
||||
handleSelect(selectedDay);
|
||||
}, [selectedDay]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className={`transition-opacity ${className}`}>
|
||||
<div className="flex items-center justify-between">
|
||||
<button onClick={previousMonth}>
|
||||
<ChevronLeftIcon />
|
||||
@@ -129,7 +125,7 @@ function Calendar({ schedules, handleSelect }: CalendarProps) {
|
||||
- <Trans i18nKey={"sidebar.available"}>запись доступна</Trans>
|
||||
</p>
|
||||
</div>
|
||||
</>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -66,10 +66,6 @@ function Chat({ className, handleClose }: ChatProps) {
|
||||
useEffect(() => {
|
||||
if (!socket) return;
|
||||
|
||||
console.log(messages);
|
||||
|
||||
console.log("CHAT Socket Init: ", socket.id);
|
||||
|
||||
socket.on("message", (socketId, message) => {
|
||||
setMessages([
|
||||
...useChatStore.getState().messages,
|
||||
|
||||
@@ -7,6 +7,7 @@ import Calendar from "./Calendar";
|
||||
import CloseIcon from "./icons/CloseIcon";
|
||||
import { useEffect, useState } from "react";
|
||||
import ky from "ky";
|
||||
import LoaderIcon from "./icons/LoaderIcon";
|
||||
|
||||
function SidebarTab1() {
|
||||
const [currentTab, setCurrentTab, setIsOpen, setSelectedDay, buildId] =
|
||||
@@ -74,13 +75,13 @@ function SidebarTab1() {
|
||||
</div>
|
||||
|
||||
<div className="sm:mt-8 mt-6">
|
||||
{schedules ? (
|
||||
{schedules && schedules.length > 0 ? (
|
||||
<Calendar
|
||||
schedules={schedules}
|
||||
handleSelect={(day) => handleSelectDay(day)}
|
||||
/>
|
||||
) : (
|
||||
"Загрузка данных..."
|
||||
<LoaderIcon className="2xl:w-8 2xl:h-8 w-6 h-6 animate-spin" />
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -5,11 +5,18 @@ import { Trans } from "react-i18next";
|
||||
import useSidebarTabStore from "../stores/useSidebarStore";
|
||||
import TimeSelector from "./TimeSelector";
|
||||
import CloseIcon from "./icons/CloseIcon";
|
||||
import { eachMinuteOfInterval, format, parse, parseISO } from "date-fns";
|
||||
import {
|
||||
addMinutes,
|
||||
eachMinuteOfInterval,
|
||||
format,
|
||||
isAfter,
|
||||
parse,
|
||||
} from "date-fns";
|
||||
import i18n from "../i18n";
|
||||
import { enUS, ru } from "date-fns/locale";
|
||||
import ky from "ky";
|
||||
import { useEffect, useState } from "react";
|
||||
import LoaderIcon from "./icons/LoaderIcon";
|
||||
|
||||
function SidebarTab2() {
|
||||
const [
|
||||
@@ -18,7 +25,6 @@ function SidebarTab2() {
|
||||
setIsOpen,
|
||||
setSelectedTime,
|
||||
selectedDay,
|
||||
selectedTime,
|
||||
buildId,
|
||||
] = useSidebarTabStore((state) => [
|
||||
state.currentTab,
|
||||
@@ -26,9 +32,9 @@ function SidebarTab2() {
|
||||
state.setIsOpen,
|
||||
state.setSelectedTime,
|
||||
state.selectedDay,
|
||||
state.selectedTime,
|
||||
state.buildId,
|
||||
]);
|
||||
const [build, setBuild] = useState<{ [key: string]: any }>();
|
||||
const [scheduledSessions, setScheduledSessions] = useState<any[]>();
|
||||
const [schedule, setSchedule] = useState<{ [key: string]: any }>();
|
||||
const [scheduleTimes, setScheduleTimes] = useState<any[]>();
|
||||
@@ -38,13 +44,43 @@ function SidebarTab2() {
|
||||
setCurrentTab(currentTab + 1);
|
||||
}
|
||||
|
||||
async function getBuild() {
|
||||
const result: { [key: string]: any } = await ky
|
||||
.get(`${import.meta.env.VITE_CRM_API_URL}/builds/${buildId}`)
|
||||
.json();
|
||||
|
||||
setBuild(result);
|
||||
}
|
||||
|
||||
async function getScheduledSessions() {
|
||||
if (!selectedDay) return;
|
||||
|
||||
const result: any[] = await ky
|
||||
.get(
|
||||
`${
|
||||
import.meta.env.VITE_CRM_API_URL
|
||||
}/scheduled_sessions/builds/${buildId}?date=${format(
|
||||
selectedDay,
|
||||
"yyyy-MM-dd"
|
||||
)}`
|
||||
)
|
||||
.json();
|
||||
|
||||
setScheduledSessions(result);
|
||||
}
|
||||
|
||||
async function getSchedule() {
|
||||
if (!selectedDay) return;
|
||||
|
||||
try {
|
||||
const result: { [key: string]: any } = await ky
|
||||
.get(
|
||||
`${import.meta.env.VITE_CRM_API_URL}/schedules/builds/${buildId}?date=${selectedDay.toISOString()}`
|
||||
`${
|
||||
import.meta.env.VITE_CRM_API_URL
|
||||
}/schedules/builds/${buildId}?date=${format(
|
||||
selectedDay,
|
||||
"yyyy-MM-dd"
|
||||
)}`
|
||||
)
|
||||
.json();
|
||||
|
||||
@@ -57,13 +93,13 @@ function SidebarTab2() {
|
||||
}
|
||||
|
||||
function generateScheduleTimes() {
|
||||
if (!schedule || !scheduledSessions) return;
|
||||
if (!selectedDay || !build || !scheduledSessions || !schedule) return;
|
||||
|
||||
const step = schedule.sessionDuration + schedule.sessionBreak;
|
||||
const times = eachMinuteOfInterval(
|
||||
{
|
||||
start: parse(schedule.startTime, "HH:mm", new Date()),
|
||||
end: parse(schedule.endTime, "HH:mm", new Date()),
|
||||
start: parse(schedule.startTime, "HH:mm", selectedDay),
|
||||
end: parse(schedule.endTime, "HH:mm", selectedDay),
|
||||
},
|
||||
{ step }
|
||||
);
|
||||
@@ -71,29 +107,24 @@ function SidebarTab2() {
|
||||
const formatTimes = times.map((time) => ({
|
||||
value: format(time, "HH:mm"),
|
||||
active:
|
||||
isAfter(time, addMinutes(new Date(), 30)) &&
|
||||
scheduledSessions.filter(
|
||||
(scheduledSession) => scheduledSession.startAt === time.toISOString()
|
||||
).length < 3,
|
||||
).length < build.sessionLimit,
|
||||
}));
|
||||
|
||||
setScheduleTimes(formatTimes);
|
||||
}
|
||||
|
||||
async function getScheduledSessions() {
|
||||
if (!selectedDay) return;
|
||||
|
||||
const result: any[] = await ky
|
||||
.get(
|
||||
`${import.meta.env.VITE_CRM_API_URL}/scheduled_sessions/builds/${buildId}?date=${selectedDay?.toISOString()}`
|
||||
)
|
||||
.json();
|
||||
|
||||
setScheduledSessions(result);
|
||||
}
|
||||
useEffect(() => {
|
||||
getBuild();
|
||||
}, [selectedDay]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!build) return;
|
||||
|
||||
getScheduledSessions();
|
||||
}, [selectedDay]);
|
||||
}, [build]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!scheduledSessions) return;
|
||||
@@ -102,6 +133,8 @@ function SidebarTab2() {
|
||||
}, [scheduledSessions]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!schedule) return;
|
||||
|
||||
generateScheduleTimes();
|
||||
}, [schedule]);
|
||||
|
||||
@@ -144,11 +177,11 @@ function SidebarTab2() {
|
||||
<div className="mt-6">
|
||||
{scheduleTimes && scheduleTimes.length > 0 ? (
|
||||
<TimeSelector
|
||||
times={scheduleTimes}
|
||||
times={scheduleTimes || []}
|
||||
handleSelect={(time) => handleSelectTime(time)}
|
||||
/>
|
||||
) : (
|
||||
"Загрузка данных..."
|
||||
<LoaderIcon className="2xl:w-8 2xl:h-8 w-6 h-6 animate-spin" />
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -20,6 +20,7 @@ function SidebarTab4() {
|
||||
name,
|
||||
phone,
|
||||
email,
|
||||
buildId,
|
||||
] = useSidebarTabStore((state) => [
|
||||
state.currentTab,
|
||||
state.setCurrentTab,
|
||||
@@ -29,6 +30,7 @@ function SidebarTab4() {
|
||||
state.name,
|
||||
state.phone,
|
||||
state.email,
|
||||
state.buildId,
|
||||
]);
|
||||
|
||||
const [isLoading, setIsLoading] = useState<boolean>(false);
|
||||
@@ -44,14 +46,15 @@ function SidebarTab4() {
|
||||
|
||||
try {
|
||||
await ky
|
||||
.post("https://coord.graff.tech/scheduled_sessions", {
|
||||
.post(`${import.meta.env.VITE_CRM_API_URL}/scheduled_sessions`, {
|
||||
json: {
|
||||
username: "test",
|
||||
name,
|
||||
phone,
|
||||
email,
|
||||
title: "nksJukovaDev",
|
||||
buildId,
|
||||
startAt,
|
||||
client: {
|
||||
name,
|
||||
phone,
|
||||
email,
|
||||
},
|
||||
},
|
||||
})
|
||||
.json();
|
||||
|
||||
@@ -4,11 +4,12 @@ import { Trans } from "react-i18next";
|
||||
interface TimeSelectorProps {
|
||||
times: any[];
|
||||
handleSelect: (time: string) => void;
|
||||
className?: string;
|
||||
}
|
||||
|
||||
function TimeSelector({ times, handleSelect }: TimeSelectorProps) {
|
||||
function TimeSelector({ times, handleSelect, className }: TimeSelectorProps) {
|
||||
return (
|
||||
<>
|
||||
<div className={`transition-opacity ${className}`}>
|
||||
<div className="grid grid-cols-4 gap-2 font-medium">
|
||||
{times.map((time, index) => (
|
||||
<button
|
||||
@@ -30,7 +31,7 @@ function TimeSelector({ times, handleSelect }: TimeSelectorProps) {
|
||||
- <Trans i18nKey={"sidebar.available"}>запись доступна</Trans>
|
||||
</p>
|
||||
</div>
|
||||
</>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
/* eslint-disable react-hooks/exhaustive-deps */
|
||||
import { useRoomContext } from "@livekit/components-react";
|
||||
import { RoomEvent, Track } from "livekit-client";
|
||||
import { Track } from "livekit-client";
|
||||
import { useEffect, useState } from "react";
|
||||
import MicroOnIcon from "./icons/MicroOnIcon";
|
||||
import MicroOffIcon from "./icons/MicroOffIcon";
|
||||
@@ -38,13 +38,13 @@ function ToggleMic({ socket, handleUpdate }: any) {
|
||||
}, [socket]);
|
||||
|
||||
useEffect(() => {
|
||||
room.on(RoomEvent.TrackMuted, (_, participant) => {
|
||||
console.log(participant);
|
||||
});
|
||||
// room.on(RoomEvent.TrackMuted, (_, participant) => {
|
||||
// console.log(participant);
|
||||
// });
|
||||
|
||||
room.on(RoomEvent.TrackUnmuted, (_, participant) => {
|
||||
console.log(participant);
|
||||
});
|
||||
// room.on(RoomEvent.TrackUnmuted, (_, participant) => {
|
||||
// console.log(participant);
|
||||
// });
|
||||
|
||||
room.on("localTrackPublished", () => {
|
||||
room.localParticipant.getTrack(Track.Source.Microphone)?.mute();
|
||||
|
||||
@@ -18,8 +18,6 @@ function AFKTimerModal() {
|
||||
}
|
||||
|
||||
async function checkAFK(interval: number) {
|
||||
console.log(afkTimerRef.current);
|
||||
|
||||
if (afkTimerRef.current && afkTimerRef.current <= 1) {
|
||||
clearInterval(interval);
|
||||
await endSession();
|
||||
|
||||
+17
-1
@@ -46,4 +46,20 @@ input {
|
||||
.lk-button {
|
||||
background: #131313 !important;
|
||||
@apply w-10 h-10 relative outline-none rounded-full shadow-lg shadow-[#131313] text-white opacity-90 flex flex-col justify-center items-center;
|
||||
}
|
||||
}
|
||||
|
||||
.entering {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.entered {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.exiting {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.exited {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
+1
-1
@@ -35,7 +35,7 @@ const router = createBrowserRouter([
|
||||
element: <HistoryPage />,
|
||||
},
|
||||
{
|
||||
path: "/scheduled",
|
||||
path: "/scheduled/:sessionId",
|
||||
element: <ScheduledPage />,
|
||||
},
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user