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
This commit is contained in:
ermek 2024-04-19 14:11:14 +05:00
parent c2dfc7fe11
commit b993f307a6
7 changed files with 464 additions and 0 deletions

View File

@ -2,6 +2,7 @@ import styled from 'styled-components'
import { Routes, Route } from 'react-router-dom' import { Routes, Route } from 'react-router-dom'
import { BrowserRouter as Router } from 'react-router-dom'; import { BrowserRouter as Router } from 'react-router-dom';
import MainPage from './pages/MainPage' import MainPage from './pages/MainPage'
import UsersGroupsUsers from './pages/UsersGroupsUsers';
type Props = {} type Props = {}
@ -15,6 +16,7 @@ export default function App({ }: Props) {
<Container> <Container>
<Routes> <Routes>
<Route path={'/'} element={<MainPage />}></Route> <Route path={'/'} element={<MainPage />}></Route>
<Route path={'/users'} element={<UsersGroupsUsers />}></Route>
</Routes> </Routes>
</Container> </Container>
</Router> </Router>

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,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,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>
)
}