Compare commits

...

2 Commits
main ... ermek

Author SHA1 Message Date
ermek b993f307a6 On branch ermek
Your branch is up to date with 'origin/ermek'.

Changes to be committed:
	modified:   src/App.tsx
	new file:   src/images/others/arrow-down-full.svg
	new file:   src/images/others/arrow-down.svg
	new file:   src/images/others/edit.svg
	new file:   src/images/others/trash.svg
	new file:   src/images/others/triangle-down.svg
	new file:   src/pages/UsersGroupsUsers.tsx
2024-04-19 14:11:14 +05:00
ermek c2dfc7fe11 On branch ermek
Changes to be committed:
	modified:   package-lock.json
	modified:   package.json
	modified:   src/App.tsx
	modified:   src/assets/theme.ts
	new file:   src/images/others/settings-middle.svg
	new file:   src/images/others/users.svg
	new file:   src/pages/MainPage.tsx
2024-04-18 16:25:54 +05:00
13 changed files with 593 additions and 52 deletions

39
package-lock.json generated
View File

@ -11,6 +11,7 @@
"@fontsource/inter": "^5.0.17",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-router-dom": "^6.22.3",
"styled-components": "^6.1.8",
"vite-plugin-svgr": "^4.2.0"
},
@ -976,6 +977,14 @@
"node": ">= 8"
}
},
"node_modules/@remix-run/router": {
"version": "1.15.3",
"resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.15.3.tgz",
"integrity": "sha512-Oy8rmScVrVxWZVOpEF57ovlnhpZ8CCPlnIIumVcV9nFdiSIrus99+Lw78ekXyGvVDlIsFJbSfmSovJUhCWYV3w==",
"engines": {
"node": ">=14.0.0"
}
},
"node_modules/@rollup/pluginutils": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.1.0.tgz",
@ -3200,6 +3209,36 @@
"node": ">=0.10.0"
}
},
"node_modules/react-router": {
"version": "6.22.3",
"resolved": "https://registry.npmjs.org/react-router/-/react-router-6.22.3.tgz",
"integrity": "sha512-dr2eb3Mj5zK2YISHK++foM9w4eBnO23eKnZEDs7c880P6oKbrjz/Svg9+nxqtHQK+oMW4OtjZca0RqPglXxguQ==",
"dependencies": {
"@remix-run/router": "1.15.3"
},
"engines": {
"node": ">=14.0.0"
},
"peerDependencies": {
"react": ">=16.8"
}
},
"node_modules/react-router-dom": {
"version": "6.22.3",
"resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.22.3.tgz",
"integrity": "sha512-7ZILI7HjcE+p31oQvwbokjk6OA/bnFxrhJ19n82Ex9Ph8fNAq+Hm/7KchpMGlTgWhUxRHMMCut+vEtNpWpowKw==",
"dependencies": {
"@remix-run/router": "1.15.3",
"react-router": "6.22.3"
},
"engines": {
"node": ">=14.0.0"
},
"peerDependencies": {
"react": ">=16.8",
"react-dom": ">=16.8"
}
},
"node_modules/resolve-from": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",

View File

@ -13,6 +13,7 @@
"@fontsource/inter": "^5.0.17",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-router-dom": "^6.22.3",
"styled-components": "^6.1.8",
"vite-plugin-svgr": "^4.2.0"
},

View File

@ -1,62 +1,24 @@
import styled from 'styled-components'
import Checkbox from './components/UI/checkbox/Checkbox'
import { ChangeEvent, useState } from 'react'
import RadioButton from './components/UI/radio-button/RadioButton'
import MainInput from './components/UI/input/main-input/MainInput'
import { Routes, Route } from 'react-router-dom'
import { BrowserRouter as Router } from 'react-router-dom';
import MainPage from './pages/MainPage'
import UsersGroupsUsers from './pages/UsersGroupsUsers';
type Props = {}
const Container = styled.div`
padding: 25px;
padding: 35px 25px 0 ;
`
export default function App({}: Props) {
const [checkboxValue, setCheckboxValue] = useState(false)
const [selectedOption, setSelectedOption] = useState<string>('option1')
const handleOptionChange = (option: string) => {
setSelectedOption(option)
}
const [inputValue, setInputValue] = useState('')
export default function App({ }: Props) {
return (
<Container>
<Checkbox value={checkboxValue} onChange={setCheckboxValue} />
<div>
<RadioButton
value={selectedOption === 'option1'}
onChange={(isChecked) =>
handleOptionChange(isChecked ? 'option1' : '')
}
name='options'
/>
Option 1
<RadioButton
value={selectedOption === 'option2'}
onChange={(isChecked) =>
handleOptionChange(isChecked ? 'option2' : '')
}
name='options'
/>
Option 2
<RadioButton
value={selectedOption === 'option3'}
onChange={(isChecked) =>
handleOptionChange(isChecked ? 'option3' : '')
}
name='options'
/>
Option 3
</div>
<MainInput
value={inputValue}
onChange={(e: ChangeEvent<HTMLInputElement>) =>
setInputValue(e.target.value)
}
placeholder='placeholder'
/>
</Container>
<Router>
<Container>
<Routes>
<Route path={'/'} element={<MainPage />}></Route>
<Route path={'/users'} element={<UsersGroupsUsers />}></Route>
</Routes>
</Container>
</Router>
)
}

View File

@ -12,6 +12,9 @@ const theme = {
p: `
font-weight: 500;
font-size: 14px;
`,
dropShadow:`
box-shadow: 0 0 10px 0 rgba(0, 0, 0, 0.1);
`
}

View File

@ -0,0 +1,3 @@
<svg width="25" height="25" viewBox="0 0 25 25" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M12.4997 6.25V18.75M12.4997 18.75L17.708 13.5417M12.4997 18.75L7.29134 13.5417" stroke="#303030" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

After

Width:  |  Height:  |  Size: 275 B

View File

@ -0,0 +1,3 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M7.41 8.84L12 13.42L16.59 8.84L18 10.25L12 16.25L6 10.25L7.41 8.84Z" fill="#303030"/>
</svg>

After

Width:  |  Height:  |  Size: 198 B

View File

@ -0,0 +1,3 @@
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M3.32507 14.045L2.23007 16.965C2.18802 17.0774 2.1792 17.1995 2.20468 17.3167C2.23015 17.434 2.28883 17.5414 2.37372 17.6262C2.4586 17.711 2.5661 17.7696 2.68337 17.7949C2.80064 17.8203 2.92274 17.8113 3.03507 17.7692L5.95423 16.6742C6.28835 16.549 6.59182 16.3538 6.84423 16.1017L15.3001 7.64584C15.3001 7.64584 15.0051 6.76168 14.1217 5.87751C13.2384 4.99418 12.3534 4.69918 12.3534 4.69918L3.89757 13.155C3.64541 13.4074 3.45021 13.7109 3.32507 14.045ZM13.5326 3.52001L14.6851 2.36751C14.8917 2.16084 15.1676 2.02918 15.4559 2.07751C15.8617 2.14418 16.4826 2.34584 17.0676 2.93168C17.6534 3.51751 17.8551 4.13751 17.9217 4.54334C17.9701 4.83168 17.8384 5.10751 17.6317 5.31418L16.4784 6.46668C16.4784 6.46668 16.1842 5.58334 15.3001 4.70001C14.4167 3.81501 13.5326 3.52001 13.5326 3.52001Z" fill="#303030"/>
</svg>

After

Width:  |  Height:  |  Size: 963 B

View File

@ -0,0 +1,4 @@
<svg width="60" height="61" viewBox="0 0 60 61" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M30 38C34.1421 38 37.5 34.6421 37.5 30.5C37.5 26.3579 34.1421 23 30 23C25.8579 23 22.5 26.3579 22.5 30.5C22.5 34.6421 25.8579 38 30 38Z" stroke="#303030" stroke-width="4"/>
<path d="M34.4137 5.8806C33.4947 5.5 32.33 5.5 30.0002 5.5C27.6705 5.5 26.5057 5.5 25.5867 5.8806C24.3617 6.38807 23.3883 7.36145 22.8808 8.58657C22.6492 9.14585 22.5585 9.79625 22.523 10.745C22.4709 12.1392 21.7559 13.4297 20.5476 14.1273C19.3393 14.8249 17.8642 14.7988 16.6307 14.1469C15.7914 13.7032 15.1828 13.4565 14.5826 13.3775C13.2678 13.2044 11.9382 13.5607 10.8861 14.368C10.0971 14.9734 9.51466 15.9822 8.34981 17.9998C7.18496 20.0174 6.60254 21.0262 6.47271 22.0123C6.29964 23.327 6.65591 24.6566 7.46319 25.7087C7.83164 26.189 8.34949 26.5925 9.15321 27.0975C10.3347 27.84 11.095 29.1047 11.0949 30.5C11.0948 31.8952 10.3346 33.1597 9.15319 33.902C8.34936 34.4072 7.83144 34.811 7.46294 35.2912C6.65566 36.3432 6.29939 37.6727 6.47249 38.9875C6.60229 39.9735 7.18471 40.9825 8.34956 43C9.51444 45.0175 10.0969 46.0265 10.8859 46.6317C11.9379 47.439 13.2676 47.7952 14.5823 47.6222C15.1825 47.5432 15.791 47.2965 16.6303 46.853C17.8639 46.201 19.3391 46.175 20.5475 46.8725C21.7558 47.5702 22.4709 48.8607 22.523 50.2552C22.5585 51.2037 22.6492 51.8542 22.8808 52.4135C23.3883 53.6385 24.3617 54.612 25.5867 55.1195C26.5057 55.5 27.6705 55.5 30.0002 55.5C32.33 55.5 33.4947 55.5 34.4137 55.1195C35.6387 54.612 36.6122 53.6385 37.1195 52.4135C37.3512 51.8542 37.442 51.2037 37.4775 50.255C37.5295 48.8607 38.2445 47.5702 39.4527 46.8725C40.661 46.1747 42.1362 46.201 43.37 46.853C44.2092 47.2965 44.8177 47.543 45.4177 47.622C46.7325 47.7952 48.0622 47.439 49.1142 46.6317C49.9032 46.0262 50.4857 45.0175 51.6505 42.9997C52.8155 40.9822 53.398 39.9735 53.5277 38.9875C53.7007 37.6727 53.3445 36.343 52.5372 35.291C52.1687 34.8107 51.6507 34.407 50.847 33.902C49.6657 33.1597 48.9055 31.895 48.9055 30.4997C48.9055 29.1045 49.6657 27.8402 50.847 27.098C51.651 26.5927 52.169 26.1892 52.5375 25.7087C53.3447 24.6568 53.701 23.3272 53.528 22.0124C53.3982 21.0264 52.8157 20.0176 51.6507 18C50.486 15.9824 49.9035 14.9736 49.1145 14.3682C48.0625 13.5609 46.7327 13.2046 45.418 13.3777C44.818 13.4567 44.2095 13.7034 43.37 14.147C42.1365 14.799 40.6612 14.825 39.453 14.1274C38.2445 13.4298 37.5295 12.1391 37.4775 10.7448C37.442 9.7962 37.3512 9.14582 37.1195 8.58657C36.6122 7.36145 35.6387 6.38807 34.4137 5.8806Z" stroke="#303030" stroke-width="4"/>
</svg>

After

Width:  |  Height:  |  Size: 2.5 KiB

View File

@ -0,0 +1,11 @@
<svg width="21" height="21" viewBox="0 0 21 21" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_320_12970)">
<path d="M7.16699 1.75033V2.58366H3.00033C2.54009 2.58366 2.16699 2.95676 2.16699 3.41699V4.25033C2.16699 4.71056 2.54009 5.08366 3.00033 5.08366H18.0003C18.4606 5.08366 18.8337 4.71056 18.8337 4.25033V3.41699C18.8337 2.95676 18.4606 2.58366 18.0003 2.58366H13.8337V1.75033C13.8337 1.29009 13.4606 0.916992 13.0003 0.916992H8.00033C7.54009 0.916992 7.16699 1.29009 7.16699 1.75033Z" fill="#303030"/>
<path d="M3.76953 6.75H17.2309L16.4456 17.3513C16.3489 18.6568 15.2615 19.6667 13.9524 19.6667H7.04798C5.73891 19.6667 4.65151 18.6568 4.55481 17.3513L3.76953 6.75Z" fill="#303030"/>
</g>
<defs>
<clipPath id="clip0_320_12970">
<rect width="20" height="20" fill="white" transform="translate(0.5 0.5)"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 863 B

View File

@ -0,0 +1,10 @@
<svg width="15" height="9" viewBox="0 0 15 9" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_320_13158)">
<path d="M0.9375 0.5625L7.6875 8.4375L14.4375 0.5625H0.9375Z" fill="#303030"/>
</g>
<defs>
<clipPath id="clip0_320_13158">
<rect width="14.625" height="9" fill="white" transform="translate(0.375)"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 358 B

View File

@ -0,0 +1,3 @@
<svg width="60" height="60" viewBox="0 0 60 60" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M47.5 35C53.0228 35 57.5 40 57.5 43.75C57.5 45.821 55.821 47.5 53.75 47.5H52.5M42.5 27.5C46.6423 27.5 50 24.1421 50 20C50 15.8579 46.6423 12.5 42.5 12.5M12.5 35C6.97715 35 2.5 40 2.5 43.75C2.5 45.821 4.17893 47.5 6.25 47.5H7.5M17.5 27.5C13.3579 27.5 10 24.1421 10 20C10 15.8579 13.3579 12.5 17.5 12.5M41.25 47.5H18.75C16.6789 47.5 15 45.821 15 43.75C15 37.5 22.5 35 30 35C37.5 35 45 37.5 45 43.75C45 45.821 43.321 47.5 41.25 47.5ZM37.5 20C37.5 24.1421 34.1423 27.5 30 27.5C25.8577 27.5 22.5 24.1421 22.5 20C22.5 15.8579 25.8577 12.5 30 12.5C34.1423 12.5 37.5 15.8579 37.5 20Z" stroke="#303030" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

After

Width:  |  Height:  |  Size: 772 B

67
src/pages/MainPage.tsx Normal file
View File

@ -0,0 +1,67 @@
import styled from "styled-components"
import { lightTheme } from "src/assets/theme"
import { ReactComponent as Users } from 'src/images/others/users.svg'
import { ReactComponent as Settings } from 'src/images/others/settings-middle.svg'
type Props = {}
const Container = styled.div`
display:flex;
flex-direction:column;
gap:10px;
h1{
${lightTheme.h1}
};
p{
${lightTheme.p}
};
`
const MainGroups = styled.div`
padding:25px;
width:100%;
background-color:white;
border-radius:12px;
display:flex;
flex-wrap:wrap;
gap:20px;
${lightTheme.dropShadow};
`
const LinkGroup = styled.div<Props>`
padding:20px;
display:flex;
flex-direction:column;
gap:20px;
justify-content:center;
align-items:center;
width:160px;
height:170px;
text-align:center;
border-radius:12px;
&:hover {
${lightTheme.dropShadow};
}
`
export default function MainPage({}: Props) {
return (
<Container>
<h1>Пользователи помогатора</h1>
<MainGroups>
<LinkGroup>
<Users />
<p>Пользователи и группы</p>
</LinkGroup>
<LinkGroup>
<Users />
Пользователи Unix
</LinkGroup>
<LinkGroup>
<Settings />
Настройки
</LinkGroup>
</MainGroups>
</Container>
)
}

View File

@ -0,0 +1,432 @@
import styled from "styled-components"
import { lightTheme } from "src/assets/theme"
import { ChangeEvent, useState } from "react"
import { ReactComponent as Search } from 'src/images/search/search.svg'
import { ReactComponent as TriangleDown } from 'src/images/others/triangle-down.svg'
import { ReactComponent as ArrowDown } from 'src/images/others/arrow-down.svg'
import { ReactComponent as ArrowDownFull } from 'src/images/others/arrow-down-full.svg'
import { ReactComponent as Trash } from 'src/images/others/trash.svg'
import { ReactComponent as Edit } from 'src/images/others/edit.svg'
import Checkbox from "src/components/UI/checkbox/Checkbox"
const Container = styled.div`
display:flex;
flex-direction:column;
gap:25px;
`
const BlockContainer = styled.div`
display:flex;
flex-direction:column;
gap:10px;
h1{
${lightTheme.h1}
};
h2{
${lightTheme.h2}
};
p{
${lightTheme.p}
};
`
const Block = styled.div`
border-radius:12px;
${lightTheme.dropShadow};
padding:20px;
display:flex;
gap:20px;
flex-direction:column;
`
const SearchInputContainer = styled.div`
display: flex;
align-items: center;
input {
width:100%;
font-weight: 400;
font-size:14px;
padding: 0 25px;
height: 37px;
outline: none;
border-radius: 12px;
border: 1px solid ${(props) => props.theme.text};
opacity: 0.5;
&:focus {
opacity: 1;
}
}
.search {
margin-left: -40px;
}
`
const TableTitleBlock = styled.div`
display:flex;
justify-content:space-between;
align-items:center;
p{
font-size:18px;
};
`
const RightBlock = styled.div`
display:flex;
gap:15px;
`
const GreenButton = styled.a`
padding:10px 15px;
background-color:${lightTheme.primary};
color:white;
border-radius:12px;
`
const TrashContainer = styled.div`
border-radius:12px;
background-color:white;
${lightTheme.dropShadow};
height:37px;
width:37px;
display: flex;
align-items: center;
justify-content: center;
`
const Rows = styled.div`
`
const RowTitle = styled.div`
display:flex;
padding: 10px;
align-items:center;
h2{
font-weight:bold;
}
`
const Row = styled.div`
border-top:solid #30303080 1px;
display:flex;
padding: 15px 10px;
justify-content:space-between;
align-items:center;
`
const Side = styled.div`
display:flex;
gap:20px;
align-items:center;
`
const BlockFooter = styled.div`
display:flex;
justify-content:space-between;
align-items:center;
`
const Paginations = styled.div`
display:flex;
gap:8px;
`
const PaginationBlock = styled.div`
border-radius:4px;
border:solid ${lightTheme.primary} 1px;
color:${lightTheme.primary};
background-color:white;
height:37px;
width:37px;
display: flex;
align-items: center;
justify-content: center;
`
const PageLimit = styled.div`
display: flex;
align-items: center;
`
const Table = styled.table`
text-align:left;
border-collapse:collapse;
`
const TableHeader = styled.thead`
font-weight:bold;
`;
const TableBody = styled.tbody`
`;
const TableRow = styled.tr`
height:67px;
`
const TableTitle = styled.th`
padding: 15px 10px;
`
const TableCell = styled.td`
padding: 15px 10px;
border-top:solid black 2px;
`
type Props = {}
export default function UsersGroupsUsers({ }: Props) {
const [searchQuery, setSearchQuery] = useState('')
const [checkboxValue, setCheckboxValue] = useState(false)
return (
<Container>
<BlockContainer>
<h1>Пользователи</h1>
<Block>
<SearchInputContainer>
<input
value={searchQuery}
onChange={(e: ChangeEvent<HTMLInputElement>) =>
setSearchQuery(e.target.value)
}
placeholder='Имя пользователя'
/>
<Search className='search' />
</SearchInputContainer>
<TableTitleBlock>
<p>Выбрано: 1</p>
<RightBlock>
<GreenButton>Добавить в группу</GreenButton>
<SearchInputContainer>
<input
value={searchQuery}
onChange={(e: ChangeEvent<HTMLInputElement>) =>
setSearchQuery(e.target.value)
}
placeholder='Имя пользователя'
/>
<TriangleDown className='search' />
</SearchInputContainer>
<TrashContainer>
<Trash className='trash'></Trash>
</TrashContainer>
</RightBlock>
</TableTitleBlock>
<Rows>
<RowTitle>
<Side>
<Checkbox value={checkboxValue} onChange={setCheckboxValue} />
<h2>Имя Пользователя</h2>
</Side>
</RowTitle>
<Row>
<Side>
<Checkbox value={checkboxValue} onChange={setCheckboxValue} />
<h2>root</h2>
</Side>
<Side>
<Edit className='edit' />
<Trash className='trash' />
</Side>
</Row>
<Row>
<Side>
<Checkbox value={checkboxValue} onChange={setCheckboxValue} />
<h2>root</h2>
</Side>
<Side>
<Edit className='edit' />
<Trash className='trash' />
</Side>
</Row>
<Row>
<Side>
<Checkbox value={checkboxValue} onChange={setCheckboxValue} />
<h2>root</h2>
</Side>
<Side>
<Edit className='edit' />
<Trash className='trash' />
</Side>
</Row>
</Rows>
<BlockFooter>
<Side>
<Paginations>
<PaginationBlock>1</PaginationBlock>
<PaginationBlock>2</PaginationBlock>
<PaginationBlock>3</PaginationBlock>
</Paginations>
<PageLimit>
Количество на странице: 5
<ArrowDown className='search' />
</PageLimit>
</Side>
<GreenButton>Создать нового пользователя</GreenButton>
</BlockFooter>
</Block>
</BlockContainer>
<BlockContainer>
<h1>Группы</h1>
<Block>
<SearchInputContainer>
<input
value={searchQuery}
onChange={(e: ChangeEvent<HTMLInputElement>) =>
setSearchQuery(e.target.value)
}
placeholder='Имя пользователя'
/>
<Search className='search' />
</SearchInputContainer>
<TableTitleBlock>
<p>Выбрано: 1</p>
<RightBlock>
<TrashContainer>
<Trash className='trash'></Trash>
</TrashContainer>
</RightBlock>
</TableTitleBlock>
<Rows>
<RowTitle>
<Side>
<Checkbox value={checkboxValue} onChange={setCheckboxValue} />
<h2>Имя Группы</h2>
</Side>
</RowTitle>
<Row>
<Side>
<Checkbox value={checkboxValue} onChange={setCheckboxValue} />
<h2>root</h2>
</Side>
<Side>
<Edit className='edit' />
<Trash className='trash' />
</Side>
</Row>
<Row>
<Side>
<Checkbox value={checkboxValue} onChange={setCheckboxValue} />
<h2>root</h2>
</Side>
<Side>
<Edit className='edit' />
<Trash className='trash' />
</Side>
</Row>
<Row>
<Side>
<Checkbox value={checkboxValue} onChange={setCheckboxValue} />
<h2>root</h2>
</Side>
<Side>
<Edit className='edit' />
<Trash className='trash' />
</Side>
</Row>
</Rows>
<BlockFooter>
<Side>
<Paginations>
<PaginationBlock>1</PaginationBlock>
<PaginationBlock>2</PaginationBlock>
<PaginationBlock>3</PaginationBlock>
</Paginations>
<PageLimit>
Количество на странице: 5
<ArrowDown className='search' />
</PageLimit>
</Side>
<GreenButton>Создать новую группу</GreenButton>
</BlockFooter>
</Block>
</BlockContainer>
<BlockContainer>
<h1>Сеансы</h1>
<Block>
<SearchInputContainer>
<input
value={searchQuery}
onChange={(e: ChangeEvent<HTMLInputElement>) =>
setSearchQuery(e.target.value)
}
placeholder='Имя пользователя'
/>
<Search className='search' />
</SearchInputContainer>
<Table>
<TableHeader>
<TableRow>
<TableTitle>
Id Сеанса
</TableTitle>
<TableTitle>
Пользователь
</TableTitle>
<TableTitle>
IP Адрес
</TableTitle>
<TableTitle>
<ArrowDownFull className='arrow-down-full'></ArrowDownFull>
Время входа
</TableTitle>
<TableTitle>
Действия
</TableTitle>
</TableRow>
</TableHeader>
<TableBody>
<TableRow>
<TableCell>
mFCQAouL3Y9E
</TableCell>
<TableCell>
root
</TableCell>
<TableCell>
111.111.111.11
</TableCell>
<TableCell>
11.04.2024 22:09
</TableCell>
<TableCell>
<GreenButton>Журнал</GreenButton>
</TableCell>
</TableRow>
<TableRow>
<TableCell>
mFCQAouL3Y9E
</TableCell>
<TableCell>
root
</TableCell>
<TableCell>
111.111.111.11
</TableCell>
<TableCell>
11.04.2024 22:09
</TableCell>
<TableCell>
<GreenButton>Журнал</GreenButton>
</TableCell>
</TableRow>
</TableBody>
</Table>
<BlockFooter>
<Side>
<Paginations>
<PaginationBlock>1</PaginationBlock>
<PaginationBlock>2</PaginationBlock>
<PaginationBlock>3</PaginationBlock>
</Paginations>
<PageLimit>
Количество на странице: 5
<ArrowDown className='search' />
</PageLimit>
</Side>
</BlockFooter>
</Block>
</BlockContainer>
</Container>
)
}