feat: DesktopCard and clean up DashboardPage layout

This commit is contained in:
2025-06-03 15:10:50 +05:00
parent 39b4815247
commit 379eae3a7b
8 changed files with 87 additions and 105 deletions
+1 -1
View File
@@ -1,6 +1,6 @@
function Badge({ count }: { count: number }) {
return (
<div className='w-[1.389vw] h-[1.389vw] rounded-full bg-[#F8F7FE] caption-xs text-[#7B60F3] flex justify-center items-center'>
<div className='w-[1.389vw] h-[1.389vw] rounded-full bg-[#F8F7FE] caption-xs text-[#7B60F3] flex justify-center items-center font-medium'>
{count}
</div>
);
+37 -65
View File
@@ -1,12 +1,13 @@
import { useMutation, useQueryClient } from "@tanstack/react-query";
import Button from "./Button";
import MoreIcon from "./icons/MoreIcon";
import api from "../utils/api";
import PlusIcon from "./icons/PlusIcon";
import { IServer } from "../types/IServer";
import useModalStore from "../stores/useModalStore";
import CreateSessionModal from "./modals/CreateSessionModal";
import SettingIcon from "./icons/SettingIcon";
import NewButton from "./NewButton";
import FlashIcon from "./icons/FlashIcon";
import CogIcon from "./icons/CogIcon";
import ChevronLeftIcon from "./icons/ChevronLeftIcon";
import PlusIcon from "./icons/PlusIcon";
interface IDesktopCardProps {
server: IServer;
@@ -46,84 +47,55 @@ export default function DesktopCard({ server }: IDesktopCardProps) {
return (
<div className='flex flex-col gap-[0.833vw] aspect-[300/211] w-[20.833vw] h-[14.653vw]'>
<div className='relative w-full h-[8.056vw] aspect-[300/116] bg-[#F6F6F6] rounded-3xl bg-[url("/images/Table.png")] bg-no-repeat bg-[top_1.111vw_left_50%] bg-[length:8.125vw]'>
<span className='absolute top-[1.111vw] right-[1.111vw] w-[0.972vw] h-[0.972vw] cursor-pointer text-[#7D7D7D]'>
<SettingIcon />
</span>
<NewButton
variant='secondary'
size='medium'
className='absolute top-[0.347vw] right-[0.347vw] cursor-pointer flex items-center justify-center'
>
<span className='text-[#7D7D7D] w-[0.972vw] h-[0.972vw]'>
<CogIcon />
</span>
</NewButton>
</div>
<div className='flex self-center justify-between items-start'>
<div className='space-y-[0.278vw] text-center'>
<p className='leading-none text-[1.111vw] title-s'>{server.name}</p>
<p className='leading-none font-[500] text-[1.111vw] title-s'>
{server.name}
</p>
<p className='caption-s text-[#7D7D7D]'>{server.location}</p>
</div>
{/* <Button
onlyIcon
size='small'
className='rounded-[0.278vw] bg-[#F5F5F5]'
>
<div className='min-w-[0.833vw] min-h-[0.833vw] text-black'>
<MoreIcon />
</div>
</Button> */}
</div>
<div className='flex justify-between items-center'>
<div className='space-y-[0.556vw]'>
{/* <div className='px-[0.556vw] py-[0.278vw] flex gap-[0.278vw] items-center bg-[#108C330D] rounded-[0.278vw] w-fit'>
{server.sessions?.[0]?.status === "started" && (
<div className='rounded-full w-[0.278vw] h-[0.278vw] bg-[#108C33]' />
)}
<p className='font-medium leading-none text-[#108C33] text-[0.556vw]'>
{server.sessions?.[0]?.status === "started"
? "Сеанс запущен"
: "Свободен"}
</p>
</div> */}
{server.sessions?.[0]?.status === "started" && (
<>
<p className='leading-none'>
{server.sessions?.[0]?.client?.fullname}
</p>
<p className='opacity-40 leading-none'>
{server.sessions?.[0]?.app?.name}
</p>
</>
)}
</div>
{/* <p className='opacity-40'>0 мин</p> */}
</div>
<div className='flex gap-[0.278vw]'>
<div className='flex gap-[0.278vw] justify-center -mt-[0.278vw]'>
{server.sessions?.[0]?.status === "started" ? (
<div className='flex items-center gap-[0.278vw]'>
{/* <Button
variant="secondary"
className="py-[0.694vw] border rounded-lg border-[#2D68F6] w-full"
>
<p className="text-center leading-none font-medium text-[#2D68F6]">
Подробнее о сеансе
</p>
</Button> */}
<Button
variant='secondary'
className='py-[0.694vw] border rounded-lg border-[#DC0404] w-full'
<NewButton
variant='primary'
onClick={() => endSession()}
className='flex gap-[0.556vw] items-center'
>
<p className='text-center leading-none font-medium text-[#DC0404]'>
Завершить сеанс
</p>
</Button>
<span className='w-[0.972vw] h-[0.972vw] flex items-center justify-center'>
<FlashIcon />
</span>
<p className='button-s font-medium'>Идёт сеанс</p>
<span className='w-[0.972vw] h-[0.972vw] flex items-center justify-center'>
<ChevronLeftIcon />
</span>
</NewButton>
</div>
) : (
<Button
variant='primary'
className='bg-[#798FFF] w-full rounded-[0.556vw]'
<NewButton
variant='cta'
size='medium'
className='self-center'
onClick={handleClickCreateSession}
>
<div className='flex gap-1 items-center'>
<span className='w-[1.389vw] h-[1.389vw]'>
<div className='flex gap-[0.556vw] items-center justify-center'>
<span className='w-[0.972vw] h-[0.972vw] flex items-center justify-center'>
<PlusIcon />
</span>
<p className='font-medium leading-[115%]'>Создать сеанс</p>
<p className='button-s'>Создать сеанс</p>
</div>
</Button>
</NewButton>
)}
</div>
</div>
+21
View File
@@ -0,0 +1,21 @@
function ChevronLeftIcon() {
return (
<svg
width={7}
height={12}
viewBox='0 0 7 12'
fill='none'
xmlns='http://www.w3.org/2000/svg'
>
<path
d='M0.75 1L5.75 6L0.75 11'
stroke='currentColor'
strokeWidth={1.2}
strokeLinecap='round'
strokeLinejoin='round'
/>
</svg>
);
}
export default ChevronLeftIcon;
+7 -13
View File
@@ -1,23 +1,17 @@
function CogIcon() {
return (
<svg
width={16}
height={16}
viewBox="0 0 16 16"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<svg viewBox='0 0 16 16' fill='none' xmlns='http://www.w3.org/2000/svg'>
<path
d="M6.095 14.39a6.67 6.67 0 0 1-2.899-1.768 2 2 0 0 0-1.727-3.28A6.7 6.7 0 0 1 1.639 6h.028a2 2 0 0 0 1.795-2.883 6.66 6.66 0 0 1 2.755-1.543 2 2 0 0 0 3.566 0 6.66 6.66 0 0 1 2.756 1.543A2 2 0 0 0 14.362 6a6.7 6.7 0 0 1 .17 3.343 2 2 0 0 0-1.727 3.28 6.67 6.67 0 0 1-2.9 1.767 2.001 2.001 0 0 0-3.81 0Z"
stroke="currentColor"
d='M6.095 14.39a6.67 6.67 0 0 1-2.899-1.768 2 2 0 0 0-1.727-3.28A6.7 6.7 0 0 1 1.639 6h.028a2 2 0 0 0 1.795-2.883 6.66 6.66 0 0 1 2.755-1.543 2 2 0 0 0 3.566 0 6.66 6.66 0 0 1 2.756 1.543A2 2 0 0 0 14.362 6a6.7 6.7 0 0 1 .17 3.343 2 2 0 0 0-1.727 3.28 6.67 6.67 0 0 1-2.9 1.767 2.001 2.001 0 0 0-3.81 0Z'
stroke='currentColor'
strokeWidth={1.2}
strokeLinejoin="round"
strokeLinejoin='round'
/>
<path
d="M8 10.333a2.333 2.333 0 1 0 0-4.666 2.333 2.333 0 0 0 0 4.666Z"
stroke="currentColor"
d='M8 10.333a2.333 2.333 0 1 0 0-4.666 2.333 2.333 0 0 0 0 4.666Z'
stroke='currentColor'
strokeWidth={1.2}
strokeLinejoin="round"
strokeLinejoin='round'
/>
</svg>
);
+18
View File
@@ -0,0 +1,18 @@
function FlashIcon() {
return (
<svg
width={20}
height={20}
viewBox='0 0 20 20'
fill='currentColor'
xmlns='http://www.w3.org/2000/svg'
>
<path
d='M8.71094 3H13.62L10.62 7.9H14.7109L8.16548 17L9.52912 10.35H5.71094L8.71094 3Z'
fill='currentColor'
/>
</svg>
);
}
export default FlashIcon;
-20
View File
@@ -1,20 +0,0 @@
function SettingIcon() {
return (
<svg viewBox='0 0 14 14' fill='none' xmlns='http://www.w3.org/2000/svg'>
<path
d='M5.3331 12.5916C4.3557 12.3006 3.48568 11.7604 2.79679 11.0446C3.05378 10.74 3.20866 10.3464 3.20866 9.91671C3.20866 8.95021 2.42516 8.16671 1.45866 8.16671C1.40019 8.16671 1.3424 8.16959 1.28541 8.17519C1.20776 7.79559 1.16699 7.4026 1.16699 7.00004C1.16699 6.39028 1.26055 5.80237 1.4341 5.24987C1.44227 5.24998 1.45046 5.25004 1.45866 5.25004C2.42516 5.25004 3.20866 4.46654 3.20866 3.50004C3.20866 3.22258 3.14408 2.96022 3.02917 2.72713C3.70376 2.09987 4.52714 1.63043 5.44052 1.37759C5.72994 1.9449 6.31978 2.33338 7.00033 2.33338C7.68087 2.33338 8.27071 1.9449 8.56013 1.37759C9.47351 1.63043 10.2969 2.09987 10.9715 2.72713C10.8566 2.96022 10.792 3.22258 10.792 3.50004C10.792 4.46654 11.5755 5.25004 12.542 5.25004C12.5502 5.25004 12.5584 5.24998 12.5666 5.24987C12.7401 5.80237 12.8337 6.39028 12.8337 7.00004C12.8337 7.4026 12.7929 7.79559 12.7152 8.17519C12.6583 8.16959 12.6005 8.16671 12.542 8.16671C11.5755 8.16671 10.792 8.95021 10.792 9.91671C10.792 10.3464 10.9469 10.74 11.2039 11.0446C10.515 11.7604 9.64495 12.3006 8.66755 12.5916C8.44198 11.886 7.78083 11.375 7.00033 11.375C6.21983 11.375 5.55868 11.886 5.3331 12.5916Z'
stroke='currentColor'
strokeWidth={1.2}
strokeLinejoin='round'
/>
<path
d='M6.99967 9.04168C8.12726 9.04168 9.04134 8.12759 9.04134 7.00001C9.04134 5.87243 8.12726 4.95834 6.99967 4.95834C5.87209 4.95834 4.95801 5.87243 4.95801 7.00001C4.95801 8.12759 5.87209 9.04168 6.99967 9.04168Z'
stroke='currentColor'
strokeWidth={1.2}
strokeLinejoin='round'
/>
</svg>
);
}
export default SettingIcon;
+1 -1
View File
@@ -3,7 +3,7 @@
body {
font-family: "TTHovesPro", sans-serif;
background-color: #f2f0fe;
background-color: #ffffff;
color: #141414;
}
+2 -5
View File
@@ -5,7 +5,6 @@ import { IServer } from "../types/IServer";
import DesktopCard from "../components/DesktopCard";
import Badge from "../components/Badge";
function DashboardPage() {
const { data: me } = useQuery({
queryKey: ["me"],
@@ -33,9 +32,9 @@ function DashboardPage() {
// }
return (
<div className='p-[0.833vw] flex gap-[0.833vw] min-h-dvh'>
<div className='flex gap-[0.833vw] min-h-dvh'>
<div className='w-[3.333vw] flex flex-col justify-between'></div>
<div className='bg-white w-full rounded-[1.667vw] border border-black/5 p-[1.667vw] flex justify-between'>
<div className='bg-white w-full flex justify-between'>
{/* <div className="w-[13.889vw] space-y-[1.667vw]">
<div className="px-[1.111vw] py-[0.556vw]">
<img
@@ -57,11 +56,9 @@ function DashboardPage() {
))}
</div>
</div>
<div className='bg-green-200 w-[13.889vw]'>...</div>
</div>
</div>
);
}
export default DashboardPage;