session files
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { Client } from "../types/IClient";
|
||||
import { Client } from "../types/Client";
|
||||
import ChevronRightIcon from "./icons/ChevronRightIcon";
|
||||
import Button from "./Button";
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import FlashIcon from "./icons/FlashIcon";
|
||||
import { Session } from "../types/ISession";
|
||||
import { Session } from "../types/Session";
|
||||
import Button from "./Button";
|
||||
import ChevronRightIcon from "./icons/ChevronRightIcon";
|
||||
import { motion } from "motion/react";
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Server } from "../types/IServer";
|
||||
import { Server } from "../types/Server";
|
||||
import useModalStore from "../stores/useModalStore";
|
||||
import CreateSessionModal from "./modals/CreateSessionModal";
|
||||
import Button from "./Button";
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { useQueryClient } from "@tanstack/react-query";
|
||||
import ChevronDownIcon from "./icons/ChevronDownIcon";
|
||||
import { IUser } from "../types/IUser";
|
||||
import { IUser } from "../types/User";
|
||||
import SearchInput from "./SearchInput";
|
||||
|
||||
function Header() {
|
||||
|
||||
@@ -3,7 +3,7 @@ import Navbar from "./Navbar";
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
import api from "../utils/api";
|
||||
import CurrentSessionCard from "./CurrentSessionCard";
|
||||
import { Session } from "../types/ISession";
|
||||
import { Session } from "../types/Session";
|
||||
import { AnimatePresence } from "motion/react";
|
||||
import Button from "./Button";
|
||||
import PlusIcon from "./icons/PlusIcon";
|
||||
|
||||
@@ -3,6 +3,7 @@ import ChevronDownIcon from "./icons/ChevronDownIcon";
|
||||
import ChevronUpIcon from "./icons/ChevronUpIcon";
|
||||
import clsx from "clsx";
|
||||
import CloseIcon from "./icons/CloseIcon";
|
||||
import Button from "./Button";
|
||||
|
||||
function NewSelect<T extends { name: string }>({
|
||||
data,
|
||||
@@ -51,16 +52,9 @@ function NewSelect<T extends { name: string }>({
|
||||
)}
|
||||
onClick={() => setIsSelectVisible(!isSelectVisible)}
|
||||
>
|
||||
<div className="button-m font-medium flex gap-[0.278vw] text-ellipsis overflow-hidden">
|
||||
<div className="button-m font-medium text-ellipsis line-clamp-1">
|
||||
{selectedValues.length > 0
|
||||
? selectedValues.map((value, index) => {
|
||||
return (
|
||||
<div key={value.name} className="">
|
||||
{value.name +
|
||||
(index !== selectedValues.length - 1 ? ", " : "")}
|
||||
</div>
|
||||
);
|
||||
})
|
||||
? selectedValues.map(({ name }) => name).join(", ")
|
||||
: placeholder}
|
||||
</div>
|
||||
<span
|
||||
@@ -79,19 +73,22 @@ function NewSelect<T extends { name: string }>({
|
||||
)}
|
||||
>
|
||||
<div
|
||||
className="flex flex-col gap-[0.278vw] p-[0.833vw] w-full bg-white rounded-[0.833vw]"
|
||||
className="flex flex-col gap-[0.278vw] px-[0.833vw] pb-[0.833vw] w-full bg-white rounded-[0.833vw] max-h-[300px] overflow-auto"
|
||||
style={{
|
||||
boxShadow: "0px 4px 40px 0px #0000000D, 0px 2px 2px 0px #0000000D",
|
||||
}}
|
||||
>
|
||||
<div
|
||||
className="text-s font-medium p-[0.833vw] text-[#7D7D7D] flex items-center gap-[0.278vw] cursor-pointer rounded-[0.278vw] hover:bg-[#F6F6F6]"
|
||||
onClick={() => setSelectedValues([])}
|
||||
>
|
||||
<span className="size-[1.111vw] flex items-center justify-center">
|
||||
<CloseIcon />
|
||||
</span>
|
||||
Выбрать всё
|
||||
<div className="bg-white sticky top-0 pt-[0.833vw]">
|
||||
<Button
|
||||
variant="secondary"
|
||||
className="!justify-start w-full text-s font-medium p-[0.833vw] text-[#7D7D7D] flex items-center gap-[0.278vw] cursor-pointer rounded-[0.278vw] hover:bg-[#F6F6F6]"
|
||||
onClick={() => setSelectedValues([])}
|
||||
>
|
||||
<span className="size-[1.111vw] flex items-center justify-center">
|
||||
<CloseIcon />
|
||||
</span>
|
||||
Выбрать всё
|
||||
</Button>
|
||||
</div>
|
||||
<div className="h-[1px] w-full bg-[#F6F6F6]" />
|
||||
{data.map((item, index) => (
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { useEffect, useState } from "react";
|
||||
import { IApp } from "../types/IApp";
|
||||
import { IApp } from "../types/App";
|
||||
import ChevronLeftIcon from "./icons/ChevronLeftIcon";
|
||||
import CloseIcon from "./icons/CloseIcon";
|
||||
import LightningIcon from "./icons/LightningIcon";
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import useModalStore from "../stores/useModalStore";
|
||||
import { Session } from "../types/ISession";
|
||||
import { Session } from "../types/Session";
|
||||
import SessionModal from "./modals/SessionModal";
|
||||
|
||||
function SessionCard({ session }: { session: Session }) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { motion } from "motion/react";
|
||||
import { Comment } from "../types/IComments";
|
||||
import { Comment } from "../types/Comments";
|
||||
import { format } from "date-fns";
|
||||
|
||||
function SessionCommentItem({ comment }: { comment: Comment }) {
|
||||
|
||||
@@ -3,7 +3,7 @@ import SendIcon from "./icons/SendIcon";
|
||||
import Button from "./Button";
|
||||
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
|
||||
import api from "../utils/api";
|
||||
import { Comment } from "../types/IComments";
|
||||
import { Comment } from "../types/Comments";
|
||||
import SessionCommentItem from "./SessionCommentItem";
|
||||
import { AnimatePresence } from "motion/react";
|
||||
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
import { Session } from "../types/Session";
|
||||
import ChevronRightIcon from "./icons/ChevronRightIcon";
|
||||
import FilledHomeIcon from "./icons/FilledHomeIcon";
|
||||
|
||||
interface SessionFilesProps {
|
||||
files: { filename: string; size: number }[];
|
||||
session: Session;
|
||||
}
|
||||
|
||||
function SessionFiles({ files, session }: SessionFilesProps) {
|
||||
return (
|
||||
<div>
|
||||
{files.map((file) => (
|
||||
<SessionFile
|
||||
{...file}
|
||||
key={file.filename}
|
||||
link={`http://${session.server.ipAddress}:3001/files/${
|
||||
session.app.fileName
|
||||
}/${new Date(session.createdAt).getTime()}/${file.filename}`}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default SessionFiles;
|
||||
|
||||
export function SessionFile({
|
||||
link,
|
||||
filename,
|
||||
size,
|
||||
}: {
|
||||
link: string;
|
||||
filename: string;
|
||||
size: number;
|
||||
}) {
|
||||
return (
|
||||
<a
|
||||
href={link}
|
||||
target="_blank"
|
||||
className="flex gap-[0.833vw] items-center px-[0.833vw] py-[0.556vw]"
|
||||
>
|
||||
<div className="p-[0.972vw] bg-[#F6F6F6] rounded-[0.556vw]">
|
||||
<span className="size-[1.389vw] text-[#7D7D7D]">
|
||||
<FilledHomeIcon />
|
||||
</span>
|
||||
</div>
|
||||
<div className="space-y-[0.278vw] flex-1">
|
||||
<p className="button-m font-medium">{filename}</p>
|
||||
<p className="text-[#BDBDBD] caption-s font-medium">{size}</p>
|
||||
</div>
|
||||
<span className="size-[1.389vw] text-[#7D7D7D]">
|
||||
<ChevronRightIcon />
|
||||
</span>
|
||||
</a>
|
||||
);
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
import clsx from "clsx";
|
||||
import { Server } from "../types/IServer";
|
||||
import { Server } from "../types/Server";
|
||||
import LightningIcon from "./icons/LightningIcon";
|
||||
|
||||
interface TableSelectorProps {
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
function FilledHomeIcon() {
|
||||
return (
|
||||
<svg viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path
|
||||
d="M12.1 17v-3.56c0-.565-.221-1.109-.615-1.51A2.08 2.08 0 0 0 10 11.307c-.557 0-1.091.225-1.485.625s-.615.944-.615 1.51V17H4.4a1.4 1.4 0 0 1-.99-.417A1.44 1.44 0 0 1 3 15.576V7.84c0-.245.063-.487.182-.701s.29-.393.498-.52l5.6-3.416a1.38 1.38 0 0 1 1.44 0l5.6 3.417A1.43 1.43 0 0 1 17 7.84v7.736c0 .378-.148.74-.41 1.007a1.4 1.4 0 0 1-.99.417z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
export default FilledHomeIcon;
|
||||
@@ -1,9 +1,9 @@
|
||||
import { Server } from "../../types/IServer.ts";
|
||||
import { Server } from "../../types/Server.ts";
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
import { IApp } from "../../types/IApp.ts";
|
||||
import { IApp } from "../../types/App.ts";
|
||||
import api from "../../utils/api.ts";
|
||||
import { Session } from "../../types/ISession.ts";
|
||||
import { Client } from "../../types/IClient.ts";
|
||||
import { Session } from "../../types/Session.ts";
|
||||
import { Client } from "../../types/Client.ts";
|
||||
import useModalStore from "../../stores/useModalStore.ts";
|
||||
import TableSelector from "../TableSelector.tsx";
|
||||
import NewInput from "../NewInput.tsx";
|
||||
|
||||
@@ -3,7 +3,7 @@ import FlashIcon from "../icons/FlashIcon";
|
||||
import Button from "../Button";
|
||||
import ChevronRightIcon from "../icons/ChevronRightIcon";
|
||||
import useModalStore from "../../stores/useModalStore";
|
||||
import { Session } from "../../types/ISession";
|
||||
import { Session } from "../../types/Session";
|
||||
import { useEffect, useState } from "react";
|
||||
import EndSessionModal from "./EndSessionModal";
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ import { useState } from "react";
|
||||
import NewInput from "../NewInput";
|
||||
import Button from "../Button";
|
||||
import useModalStore from "../../stores/useModalStore";
|
||||
import { Server } from "../../types/IServer";
|
||||
import { Server } from "../../types/Server";
|
||||
import { useQueryClient } from "@tanstack/react-query";
|
||||
import { useMutation } from "@tanstack/react-query";
|
||||
import api from "../../utils/api";
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { useMutation } from "@tanstack/react-query";
|
||||
import { useQueryClient } from "@tanstack/react-query";
|
||||
import useModalStore from "../../stores/useModalStore";
|
||||
import { Session } from "../../types/ISession";
|
||||
import { Session } from "../../types/Session";
|
||||
import Button from "../Button";
|
||||
import CurrentSessionModal from "./CurrentSessionModal";
|
||||
import api from "../../utils/api";
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Session } from "../../types/ISession";
|
||||
import { Session } from "../../types/Session";
|
||||
import { format } from "date-fns";
|
||||
import { ru } from "date-fns/locale";
|
||||
import getIntervalDuration from "../../utils/interval-duration";
|
||||
@@ -7,11 +7,29 @@ import Button from "../Button";
|
||||
import ChevronRightIcon from "../icons/ChevronRightIcon";
|
||||
import Badge from "../Badge";
|
||||
import ClientCard from "../ClientCard";
|
||||
import DownloadIcon from "../icons/DownloadIcon";
|
||||
import ShareIcon from "../icons/ShareIcon";
|
||||
import SessionComments from "../SessionComments";
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
import api from "../../utils/api";
|
||||
import { useEffect } from "react";
|
||||
import SessionFiles from "../SessionFiles";
|
||||
|
||||
function SessionModal({ session }: { session: Session }) {
|
||||
const { data } = useQuery({
|
||||
queryKey: ["file-list"],
|
||||
queryFn: () =>
|
||||
api
|
||||
.get("files", {
|
||||
searchParams: {
|
||||
sessionId: session.id,
|
||||
},
|
||||
})
|
||||
.json<string[]>(),
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
console.log(data);
|
||||
}, [data]);
|
||||
|
||||
return (
|
||||
<div className="bg-[#FFFFFF] w-[49.722vw] rounded-[2.222vw]">
|
||||
<div className="w-full flex justify-center items-center h-[4.861vw] border-b-1 border-[#D6D6D6]">
|
||||
@@ -111,7 +129,7 @@ function SessionModal({ session }: { session: Session }) {
|
||||
<h3 className="title-s flex items-center font-medium gap-[0.556vw]">
|
||||
<span>Документы по сеансу</span> <Badge count={4} />
|
||||
</h3>
|
||||
<div className="flex w-full gap-[0.556vw]">
|
||||
{/* <div className="flex w-full gap-[0.556vw]">
|
||||
<Button variant="primary" size="large" className="w-full">
|
||||
<span className="w-[1.111vw] h-[1.111vw] text-[#7B60F3]">
|
||||
<DownloadIcon />
|
||||
@@ -123,7 +141,8 @@ function SessionModal({ session }: { session: Session }) {
|
||||
<ShareIcon />
|
||||
</span>
|
||||
</Button>
|
||||
</div>
|
||||
</div> */}
|
||||
{data && <SessionFiles files={data} session={session} />}
|
||||
</div>
|
||||
</div>
|
||||
<SessionComments sessionId={session.id} />
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
import { IUser } from "../types/IUser";
|
||||
import { IUser } from "../types/User";
|
||||
import api from "../utils/api";
|
||||
import { Server } from "../types/IServer";
|
||||
import { Server } from "../types/Server";
|
||||
import DesktopCard from "../components/DesktopCard";
|
||||
import Badge from "../components/Badge";
|
||||
import { Session } from "../types/ISession";
|
||||
import { Session } from "../types/Session";
|
||||
import SessionCard from "../components/SessionCard";
|
||||
import Button from "../components/Button";
|
||||
import ChevronRightIcon from "../components/icons/ChevronRightIcon";
|
||||
|
||||
@@ -4,7 +4,7 @@ import useAuthStore from "../stores/useAuthStore";
|
||||
import api from "../utils/api";
|
||||
import { useState } from "react";
|
||||
import { HTTPError } from "ky";
|
||||
import { IError } from "../types/IError";
|
||||
import { IError } from "../types/Error";
|
||||
import { useNavigate } from "react-router";
|
||||
import Button from "../components/Button";
|
||||
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
import { Navigate, Outlet } from 'react-router';
|
||||
import useAuthStore from '../stores/useAuthStore';
|
||||
import api from '../utils/api';
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
import { IUser } from '../types/IUser';
|
||||
import { Navigate, Outlet } from "react-router";
|
||||
import useAuthStore from "../stores/useAuthStore";
|
||||
import api from "../utils/api";
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
import { IUser } from "../types/User";
|
||||
|
||||
function ProtectedPage() {
|
||||
const { token } = useAuthStore();
|
||||
|
||||
const { data: user, isLoading } = useQuery({
|
||||
queryKey: ['me'],
|
||||
queryFn: () => api.get('auth/me').json<IUser>(),
|
||||
queryKey: ["me"],
|
||||
queryFn: () => api.get("auth/me").json<IUser>(),
|
||||
enabled: !!token,
|
||||
});
|
||||
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
import api from "../utils/api";
|
||||
import { IUser } from "../types/IUser";
|
||||
import { Session } from "../types/ISession";
|
||||
import { IUser } from "../types/User";
|
||||
import { Session } from "../types/Session";
|
||||
import Input from "../components/Input";
|
||||
import Select from "../components/Select";
|
||||
import { useState } from "react";
|
||||
import { IApp } from "../types/IApp";
|
||||
import { IApp } from "../types/App";
|
||||
import { useDebounce } from "@uidotdev/usehooks";
|
||||
import SessionCard from "../components/SessionCard";
|
||||
import { groupByCreatedAt } from "../utils/groupByCreatedAt";
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { IApp } from "../types/IApp.ts";
|
||||
import { IApp } from "../types/App.ts";
|
||||
import api from "../utils/api.ts";
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Server } from "../types/IServer.ts";
|
||||
import { Server } from "../types/Server.ts";
|
||||
import api from "../utils/api.ts";
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { IApp } from "./IApp";
|
||||
import { Server } from "./IServer";
|
||||
import { IUser } from "./IUser";
|
||||
import { IApp } from "./App";
|
||||
import { Server } from "./Server";
|
||||
import { IUser } from "./User";
|
||||
|
||||
export interface ICompany {
|
||||
id: string;
|
||||
@@ -1,5 +1,5 @@
|
||||
import { IApp as App } from "./IApp";
|
||||
import { Session } from "./ISession";
|
||||
import { IApp as App } from "./App";
|
||||
import { Session } from "./Session";
|
||||
|
||||
export interface Server {
|
||||
id: string;
|
||||
@@ -10,4 +10,5 @@ export interface Server {
|
||||
sessions?: Session[];
|
||||
apps?: App[];
|
||||
status: "online" | "offline";
|
||||
ipAddress: string;
|
||||
}
|
||||
@@ -1,8 +1,8 @@
|
||||
import { IApp as App } from "./IApp";
|
||||
import { Comment } from "./IComments";
|
||||
import { IOwner as Owner } from "./IOwner";
|
||||
import { Server } from "./IServer";
|
||||
import { Client } from "./IClient";
|
||||
import { IApp as App } from "./App";
|
||||
import { Comment } from "./Comments";
|
||||
import { IOwner as Owner } from "./Owner";
|
||||
import { Server } from "./Server";
|
||||
import { Client } from "./Client";
|
||||
|
||||
export interface Session {
|
||||
id: string;
|
||||
@@ -1,4 +1,4 @@
|
||||
import { ICompany } from "./ICompany";
|
||||
import { ICompany } from "./Company";
|
||||
|
||||
export interface IUser {
|
||||
id: string;
|
||||
Reference in New Issue
Block a user