готовая 4лаба
This commit is contained in:
parent
ad972b3004
commit
1e0a05314a
13
favicon.svg
Normal file
13
favicon.svg
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
<svg width="142" height="72" viewBox="0 0 142 72" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M0.955078 72V65.8477L8.91406 64.4805V8.47461L0.955078 7.10742V0.90625H26.4922V7.10742L18.5332 8.47461V33.0352H52.5176V8.47461L44.5586 7.10742V0.90625H52.5176H62.1367H70.0957V7.10742L62.1367 8.47461V64.4805L70.0957 65.8477V72H44.5586V65.8477L52.5176 64.4805V40.6035H18.5332V64.4805L26.4922 65.8477V72H0.955078ZM77.5176 72V65.8477L85.4766 64.4805V8.47461L77.5176 7.10742V0.90625H103.055V7.10742L95.0957 8.47461V32.9375H102.859L118.924 9.79297C121.561 6.14714 123.855 3.67318 125.809 2.37109C127.762 1.03646 130.024 0.369141 132.596 0.369141C134.126 0.369141 135.411 0.564453 136.453 0.955078C137.527 1.31315 138.65 1.85026 139.822 2.56641L138.406 9.35352C137.527 9.19076 136.746 9.06055 136.062 8.96289C135.411 8.83268 134.76 8.76758 134.109 8.76758C132.579 8.76758 131.277 9.17448 130.203 9.98828C129.161 10.8021 127.941 12.1855 126.541 14.1387L111.258 35.4277L134.891 64.627L141.58 65.8477V72H118.24V65.8477L123.66 65.1641L123.465 64.9199L104.275 41.043H95.0957V64.4805L103.055 65.8477V72H77.5176Z"/>
|
||||||
|
<style>
|
||||||
|
path {
|
||||||
|
fill: black;
|
||||||
|
}
|
||||||
|
@media (prefers-color-scheme: dark) {
|
||||||
|
path {
|
||||||
|
fill: white;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.2 KiB |
@ -3,6 +3,7 @@
|
|||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8" />
|
<meta charset="UTF-8" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
<link rel="shortcut icon" href="favicon.svg" type="image/svg+xml" />
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="root" class="min-vh-100 d-flex flex-column"></div>
|
<div id="root" class="min-vh-100 d-flex flex-column"></div>
|
||||||
|
14
jsconfig.json
Normal file
14
jsconfig.json
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"module": "ESNext",
|
||||||
|
"moduleResolution": "Node",
|
||||||
|
"target": "ES2020",
|
||||||
|
"jsx": "react",
|
||||||
|
"strictNullChecks": true,
|
||||||
|
"strictFunctionTypes": true
|
||||||
|
},
|
||||||
|
"exclude": [
|
||||||
|
"node_modules",
|
||||||
|
"**/node_modules/*"
|
||||||
|
]
|
||||||
|
}
|
@ -1,15 +1,20 @@
|
|||||||
import PropTypes from 'prop-types'
|
import PropTypes from 'prop-types'
|
||||||
import Header from './components/header/header'
|
import Header from './components/header/header'
|
||||||
import Footer from './components/footer/footer'
|
import Footer from './components/footer/footer'
|
||||||
|
import { Outlet } from 'react-router-dom';
|
||||||
import { Container } from 'react-bootstrap'
|
import { Container } from 'react-bootstrap'
|
||||||
|
import BottomMenu from './components/bottommenu/bottommenu';
|
||||||
|
import LeftMenu from './components/leftmenu/leftmenu';
|
||||||
|
|
||||||
const App = ({ routes }) => {
|
const App = ({ routes }) => {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Header routes={routes}></Header>
|
<Header routes={routes}></Header>
|
||||||
<Container as="main" className="px-1 px-sm-2 px-lg-4 pt-2 pt-sm-4 d-flex position-relative flex-fill">
|
<Container as="main" className="px-1 px-sm-2 px-lg-4 pt-2 pt-sm-4 d-flex position-relative flex-fill">
|
||||||
Привет
|
<LeftMenu routes={routes} />
|
||||||
|
<Outlet />
|
||||||
</Container>
|
</Container>
|
||||||
|
<BottomMenu routes={routes} />
|
||||||
<Footer></Footer>
|
<Footer></Footer>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
BIN
src/assets/gachi.jpg
Normal file
BIN
src/assets/gachi.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 14 KiB |
BIN
src/assets/korgi.jpg
Normal file
BIN
src/assets/korgi.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 140 KiB |
11
src/components/bottommenu/bottommenu.css
Normal file
11
src/components/bottommenu/bottommenu.css
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
.bottom-menu {
|
||||||
|
background-color: #235D70;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bottom-menu * {
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bottom-menu span {
|
||||||
|
font-size: smaller;
|
||||||
|
}
|
26
src/components/bottommenu/bottommenu.jsx
Normal file
26
src/components/bottommenu/bottommenu.jsx
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
import PropTypes from 'prop-types';
|
||||||
|
import { Link } from 'react-router-dom';
|
||||||
|
import './bottommenu.css';
|
||||||
|
|
||||||
|
const BottomMenu = ({ routes }) => {
|
||||||
|
const pages = routes.filter((route) => route.showInBottomMenu);
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<div className="bottom-menu d-flex d-sm-none justify-content-around sticky-bottom">
|
||||||
|
{
|
||||||
|
pages.map((route) =>
|
||||||
|
<Link to={route.path} key={route.path} className="bottom-menu-item d-flex flex-column rounded-2 align-items-center py-1">
|
||||||
|
{route.menuIcon}
|
||||||
|
<span>{route.title}</span>
|
||||||
|
</Link>)
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
BottomMenu.propTypes = {
|
||||||
|
routes: PropTypes.array,
|
||||||
|
};
|
||||||
|
|
||||||
|
export default BottomMenu;
|
63
src/components/center/center.css
Normal file
63
src/components/center/center.css
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
.center {
|
||||||
|
width: 70%;
|
||||||
|
z-index: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-message-trucated-text {
|
||||||
|
max-width: 60vw;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (min-width: 992px) {
|
||||||
|
.user-message-trucated-text {
|
||||||
|
max-width: 30vw;
|
||||||
|
}
|
||||||
|
|
||||||
|
.center {
|
||||||
|
width: 40%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: 576px) {
|
||||||
|
.user-message-trucated-text {
|
||||||
|
max-width: 70vw;
|
||||||
|
}
|
||||||
|
|
||||||
|
.center {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#post-editor {
|
||||||
|
min-height: calc(1em + 26px);
|
||||||
|
}
|
||||||
|
|
||||||
|
#title-image-preview {
|
||||||
|
width: 100%;
|
||||||
|
min-height: 100px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
font-size: 50px;
|
||||||
|
cursor: pointer;
|
||||||
|
border: solid;
|
||||||
|
border-width: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#title-image-preview i {
|
||||||
|
opacity: 0.3;
|
||||||
|
transition: opacity .3s;
|
||||||
|
}
|
||||||
|
|
||||||
|
#title-image-preview:hover i {
|
||||||
|
opacity: 1.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#input-title-image {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
#selected-title-image {
|
||||||
|
width: 100%;
|
||||||
|
display: none;
|
||||||
|
}
|
18
src/components/center/center.jsx
Normal file
18
src/components/center/center.jsx
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
import PropTypes from 'prop-types';
|
||||||
|
import './center.css';
|
||||||
|
|
||||||
|
const Center = ({ children }) => {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<div className="center d-flex flex-column">
|
||||||
|
{children}
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Center.propTypes = {
|
||||||
|
children: PropTypes.node,
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Center;
|
0
src/components/chatrow/chatrow.css
Normal file
0
src/components/chatrow/chatrow.css
Normal file
24
src/components/chatrow/chatrow.jsx
Normal file
24
src/components/chatrow/chatrow.jsx
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
import './chatrow.css';
|
||||||
|
|
||||||
|
const ChatRow = () => {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<a className="people-row border-bottom border-dark p-2 d-flex justify-content-between align-items-center">
|
||||||
|
<div className="d-flex justify-content-start align-items-center" style={{ fontSize: "small" }}>
|
||||||
|
<img src="/src/assets/gachi.jpg" className="user-avatar avatar-small img-fluid rounded-circle" />
|
||||||
|
<div className="user-info ms-2 d-flex flex-column justify-content-center w-100">
|
||||||
|
<div className="user-name">Валерий Никифоров</div>
|
||||||
|
<div className="user-message-trucated-text px-2 py-1 rounded-3 text-truncate" style={{ fontSize: "smaller" }}>
|
||||||
|
Табличку по баллам сведу к понедельнику.
|
||||||
|
Больше никакие лабы присылать нельзя, литкод
|
||||||
|
можно. Плюс поверьте, что у вас 7 ответов по
|
||||||
|
лекциям
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</a >
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ChatRow;
|
0
src/components/friendrow/friendrow.css
Normal file
0
src/components/friendrow/friendrow.css
Normal file
24
src/components/friendrow/friendrow.jsx
Normal file
24
src/components/friendrow/friendrow.jsx
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
import './friendrow.css'
|
||||||
|
|
||||||
|
const FriendRow = () => {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<div className="people-row border-bottom border-dark p-2 d-flex justify-content-between align-items-center">
|
||||||
|
<a className="d-flex justify-content-start align-items-center" style={{ fontSize: "small" }}>
|
||||||
|
<img src="/src/assets/gachi.jpg" className="user-avatar avatar-small img-fluid rounded-circle" />
|
||||||
|
<div className="user-info ms-2 d-flex flex-column justify-content-center">
|
||||||
|
<div className="user-name">
|
||||||
|
Валентина Лаврентьева
|
||||||
|
</div>
|
||||||
|
<div className="user-meta">
|
||||||
|
г. Калининград, 20 лет
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
<button className="btn btn-close" title="Удалить из друзей"></button>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default FriendRow;
|
@ -8,8 +8,8 @@ const Header = ({ routes }) => {
|
|||||||
const indexPageLink = routes.filter((route) => route.index === false).shift();
|
const indexPageLink = routes.filter((route) => route.index === false).shift();
|
||||||
const currentPage = routes.filter((route) => route.path === location.pathname)[0];
|
const currentPage = routes.filter((route) => route.path === location.pathname)[0];
|
||||||
return (
|
return (
|
||||||
<header>
|
<header className='sticky-top'>
|
||||||
<Navbar className='sticky-top'>
|
<Navbar>
|
||||||
<Container fluid className='d-flex justify-content-between position-relative'>
|
<Container fluid className='d-flex justify-content-between position-relative'>
|
||||||
<Navbar.Brand as={Link} to={indexPageLink?.path ?? '/'}>
|
<Navbar.Brand as={Link} to={indexPageLink?.path ?? '/'}>
|
||||||
<span className='logo-small d-sm-none'>
|
<span className='logo-small d-sm-none'>
|
||||||
|
11
src/components/leftmenu/leftmenu.css
Normal file
11
src/components/leftmenu/leftmenu.css
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
#left-menu {
|
||||||
|
--bs-border-color: var(--alternative-font-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.left-menu-item {
|
||||||
|
transition: .1s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.left-menu-item:hover {
|
||||||
|
background-color: #e8e8e8;
|
||||||
|
}
|
28
src/components/leftmenu/leftmenu.jsx
Normal file
28
src/components/leftmenu/leftmenu.jsx
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
import PropTypes from "prop-types";
|
||||||
|
import { Link } from 'react-router-dom';
|
||||||
|
import './leftmenu.css';
|
||||||
|
|
||||||
|
const LeftMenu = ({ routes }) => {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<div
|
||||||
|
id="left-menu"
|
||||||
|
className="p-3 d-none d-sm-flex flex-column justify-content-center align-content-around border rounded-2 position-fixed"
|
||||||
|
>
|
||||||
|
{
|
||||||
|
routes.map((route) =>
|
||||||
|
<Link to={route.path} key={route.path} className="left-menu-item d-flex flex-row align-items-center rounded-2 py-1 px-2">
|
||||||
|
{route.menuIcon}
|
||||||
|
<span className="ms-2 d-none d-lg-block">{route.title}</span>
|
||||||
|
</Link>)
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
LeftMenu.propTypes = {
|
||||||
|
routes: PropTypes.array,
|
||||||
|
};
|
||||||
|
|
||||||
|
export default LeftMenu;
|
45
src/components/post/post.css
Normal file
45
src/components/post/post.css
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
.post {
|
||||||
|
background-color: var(--alternative-backgrond-color);
|
||||||
|
--bs-border-color: var(--alternative-font-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.post-meta {
|
||||||
|
font-size: small;
|
||||||
|
}
|
||||||
|
|
||||||
|
.counter-block {
|
||||||
|
transition: .1s;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.counter-block:hover {
|
||||||
|
background-color: #e8e8e8;
|
||||||
|
}
|
||||||
|
|
||||||
|
.post-body-img {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.post-body a {
|
||||||
|
color: #4a9cb7;
|
||||||
|
text-decoration: none;
|
||||||
|
background-image: linear-gradient(currentColor, currentColor);
|
||||||
|
background-position: 0% 100%;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-size: 0% 2px;
|
||||||
|
transition: background-size .3s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.post-body a:hover {
|
||||||
|
background-size: 100% 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.post-body-text {
|
||||||
|
white-space: pre-wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.avatar-small {
|
||||||
|
width: 35px;
|
||||||
|
height: 35px;
|
||||||
|
object-fit: cover;
|
||||||
|
}
|
111
src/components/post/post.jsx
Normal file
111
src/components/post/post.jsx
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
import './post.css';
|
||||||
|
|
||||||
|
const Post = () => {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<div className="post mb-2 mb-sm-4 w-100 d-flex flex-column border rounded-2">
|
||||||
|
<div className="post-header py-1 px-2 d-flex border-bottom justify-content-between align-items-center">
|
||||||
|
<a className="d-flex justify-content-start align-items-center">
|
||||||
|
<div className="post-author-avatar-wrapper">
|
||||||
|
<img
|
||||||
|
src="/src/assets/gachi.jpg" className="post-author-avatar avatar-small rounded-circle" />
|
||||||
|
</div>
|
||||||
|
<div className="post-meta ms-2 d-flex flex-column justify-content-center">
|
||||||
|
<div className="post-author-name">
|
||||||
|
Алексей Смирнов
|
||||||
|
</div>
|
||||||
|
<div className="post-publication-datetime">
|
||||||
|
15 сентября, 15:22
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</a>
|
||||||
|
<a>
|
||||||
|
<i className="bi bi-three-dots fs-4"></i>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<div className="post-body">
|
||||||
|
<div className="post-body-text m-2">
|
||||||
|
<p>
|
||||||
|
Корги – королевская порода с дружелюбным
|
||||||
|
характером
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Привет, друзья! Сегодня я хочу
|
||||||
|
рассказать вам о замечательной породе
|
||||||
|
собак – корги. Эти милые создания с
|
||||||
|
короткими лапами и длинными ушами
|
||||||
|
покорили сердца многих людей, и не зря!
|
||||||
|
Корги – это небольшие собаки, которые
|
||||||
|
произошли из Уэльса. Они были выведены
|
||||||
|
для охоты на зайцев и других мелких
|
||||||
|
животных.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<img src="/src/assets/korgi.jpg" className="post-body-img img-fluid" />
|
||||||
|
</div>
|
||||||
|
<div className="post-footer py-1 px-2 border-top d-flex">
|
||||||
|
<div className="counter-block likes-block px-2 me-1 d-flex align-items-center rounded-4">
|
||||||
|
<svg
|
||||||
|
height="24"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
width="24"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
>
|
||||||
|
<g fill="none" fillRule="evenodd">
|
||||||
|
<path d="M0 0h24v24H0z"></path>
|
||||||
|
<path
|
||||||
|
d="M16 4a5.95 5.95 0 0 0-3.89 1.7l-.12.11-.12-.11A5.96 5.96 0 0 0 7.73 4 5.73 5.73 0 0 0 2 9.72c0 3.08 1.13 4.55 6.18 8.54l2.69 2.1c.66.52 1.6.52 2.26 0l2.36-1.84.94-.74c4.53-3.64 5.57-5.1 5.57-8.06A5.73 5.73 0 0 0 16.27 4zm.27 1.8a3.93 3.93 0 0 1 3.93 3.92v.3c-.08 2.15-1.07 3.33-5.51 6.84l-2.67 2.08a.04.04 0 0 1-.04 0L9.6 17.1l-.87-.7C4.6 13.1 3.8 11.98 3.8 9.73A3.93 3.93 0 0 1 7.73 5.8c1.34 0 2.51.62 3.57 1.92a.9.9 0 0 0 1.4-.01c1.04-1.3 2.2-1.91 3.57-1.91z"
|
||||||
|
fill="currentColor"
|
||||||
|
fillRule="nonzero"
|
||||||
|
></path>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
<span className="count ms-1">734</span>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className="counter-block comments-block px-2 me-1 d-flex align-items-center rounded-4"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
height="24"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
width="24"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
>
|
||||||
|
<g fill="none" fillRule="evenodd">
|
||||||
|
<path d="M0 0h24v24H0z"></path>
|
||||||
|
<path
|
||||||
|
d="M16.9 4H7.1c-1.15 0-1.73.11-2.35.44-.56.3-1 .75-1.31 1.31C3.11 6.37 3 6.95 3 8.1v5.8c0 1.15.11 1.73.44 2.35.3.56.75 1 1.31 1.31l.15.07c.51.25 1.04.35 1.95.37h.25v2.21c0 .44.17.85.47 1.16l.12.1c.64.55 1.6.52 2.21-.08L13.37 18h3.53c1.15 0 1.73-.11 2.35-.44.56-.3 1-.75 1.31-1.31.33-.62.44-1.2.44-2.35V8.1c0-1.15-.11-1.73-.44-2.35a3.17 3.17 0 0 0-1.31-1.31A4.51 4.51 0 0 0 16.9 4zM6.9 5.8h9.99c.88 0 1.18.06 1.5.23.25.13.44.32.57.57.17.32.23.62.23 1.5v6.16c-.02.61-.09.87-.23 1.14-.13.25-.32.44-.57.57-.32.17-.62.23-1.5.23h-4.02a.9.9 0 0 0-.51.26l-3.47 3.4V17.1c0-.5-.4-.9-.9-.9H6.74a2.3 2.3 0 0 1-1.14-.23 1.37 1.37 0 0 1-.57-.57c-.17-.32-.23-.62-.23-1.5V7.74c.02-.61.09-.87.23-1.14.13-.25.32-.44.57-.57.3-.16.58-.22 1.31-.23z"
|
||||||
|
fill="currentColor"
|
||||||
|
fillRule="nonzero"
|
||||||
|
></path>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
<span className="count ms-1">344</span>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className="counter-block replies-block px-2 d-flex align-items-center rounded-4"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
height="24"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
width="24"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
>
|
||||||
|
<g fill="none" fillRule="evenodd">
|
||||||
|
<path d="M0 0h24v24H0z"></path>
|
||||||
|
<path
|
||||||
|
d="M12 3.73c-1.12.07-2 1-2 2.14v2.12h-.02a9.9 9.9 0 0 0-7.83 10.72.9.9 0 0 0 1.61.46l.19-.24a9.08 9.08 0 0 1 5.84-3.26l.2-.03.01 2.5a2.15 2.15 0 0 0 3.48 1.69l7.82-6.14a2.15 2.15 0 0 0 0-3.38l-7.82-6.13c-.38-.3-.85-.46-1.33-.46zm.15 1.79c.08 0 .15.03.22.07l7.82 6.14a.35.35 0 0 1 0 .55l-7.82 6.13a.35.35 0 0 1-.57-.28V14.7a.9.9 0 0 0-.92-.9h-.23l-.34.02c-2.28.14-4.4.98-6.12 2.36l-.17.15.02-.14a8.1 8.1 0 0 1 6.97-6.53.9.9 0 0 0 .79-.9V5.87c0-.2.16-.35.35-.35z"
|
||||||
|
fill="currentColor"
|
||||||
|
fillRule="nonzero"
|
||||||
|
></path>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
<span className="count ms-1">1</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Post;
|
7
src/components/postinputform/postinputform.css
Normal file
7
src/components/postinputform/postinputform.css
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
#post-editor {
|
||||||
|
--bs-border-color: var(--alternative-font-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
#title-image-block * {
|
||||||
|
--bs-border-color: var(--alternative-font-color);
|
||||||
|
}
|
31
src/components/postinputform/postinputform.jsx
Normal file
31
src/components/postinputform/postinputform.jsx
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
import './postinputform.css';
|
||||||
|
import { Camera } from 'react-bootstrap-icons';
|
||||||
|
|
||||||
|
const PostInputForm = () => {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<textarea placeholder="Что нового?" id="post-editor" className="border rounded-2 mb-2 p-2"></textarea>
|
||||||
|
<div id="title-image-block">
|
||||||
|
<input id="check-title-image" type="checkbox" style={{ display: "none" }} />
|
||||||
|
<input id="input-title-image" className='border' name="titleImage" accept="image/*" type="file" />
|
||||||
|
<label id="title-image-preview" htmlFor="input-title-image" title="Добавить изображение" className="border rounded-2 mb-2">
|
||||||
|
<Camera id="empty-title-image" />
|
||||||
|
<img id="selected-title-image" className="rounded-2" />
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<button className="btn btn-primary mb-2" id="post-publication-button">
|
||||||
|
Опубликовать
|
||||||
|
</button>
|
||||||
|
<div className="d-none d-flex mb-2 w-100" id="edit-block">
|
||||||
|
<button className="btn btn-danger me-2 w-100" id="edit-post-button-cancel">
|
||||||
|
Отмена
|
||||||
|
</button>
|
||||||
|
<button className="btn btn-success w-100" id="edit-post-button-accept">
|
||||||
|
Применить
|
||||||
|
</button>
|
||||||
|
</div >
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default PostInputForm;
|
35
src/components/userprofileblock/userprofileblock.jsx
Normal file
35
src/components/userprofileblock/userprofileblock.jsx
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
import './userprofileblock.css';
|
||||||
|
import { People, Calendar as Calendar, GeoAlt } from 'react-bootstrap-icons';
|
||||||
|
|
||||||
|
const UserProfileBlock = () => {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<div className="user-profile p-3 mb-2 mb-sm-4 w-100 d-flex flex-column flex-sm-row border rounded-2 border-dark">
|
||||||
|
<div className='d-flex align-items-center justify-content-center me-0 me-sm-3 mb-3 mb-sm-0'>
|
||||||
|
<img src="/src/assets/gachi.jpg" className="user-photo rounded-2 img-fluid" />
|
||||||
|
</div>
|
||||||
|
<div className="user-meta-wrapper d-flex flex-column">
|
||||||
|
<span className="fs-5 mb-2">Алексей Смирнов</span>
|
||||||
|
<span style={{ fontSize: "small" }} className="mb-2 fst-italic">
|
||||||
|
Прежде чем задать вопрос, подумай, хочешь ли ты
|
||||||
|
знать на него правдивый ответ...
|
||||||
|
</span>
|
||||||
|
<span style={{ fontSize: "small" }} className='d-flex align-items-center'>
|
||||||
|
<GeoAlt className='me-1' />
|
||||||
|
Ульяновск
|
||||||
|
</span>
|
||||||
|
<span style={{ fontSize: "small" }} className='d-flex align-items-center'>
|
||||||
|
<Calendar className='me-1' />
|
||||||
|
23.04.1998г.
|
||||||
|
</span>
|
||||||
|
<span style={{ fontSize: "small" }} className='d-flex align-items-center'>
|
||||||
|
<People className='me-1' />
|
||||||
|
234 друга
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div >
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default UserProfileBlock;
|
3
src/components/wrapper/wrapper.css
Normal file
3
src/components/wrapper/wrapper.css
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
.wrapper {
|
||||||
|
width: 100%;
|
||||||
|
}
|
18
src/components/wrapper/wrapper.jsx
Normal file
18
src/components/wrapper/wrapper.jsx
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
import PropTypes from 'prop-types';
|
||||||
|
import './wrapper.css';
|
||||||
|
|
||||||
|
const Wrapper = ({ children }) => {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<div className="wrapper d-flex justify-content-center">
|
||||||
|
{children}
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Wrapper.propTypes = {
|
||||||
|
children: PropTypes.node,
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Wrapper;
|
@ -25,6 +25,7 @@
|
|||||||
--dark-font-color: var(--color-white);
|
--dark-font-color: var(--color-white);
|
||||||
--light-font-color: var(--color-black);
|
--light-font-color: var(--color-black);
|
||||||
--alternative-font-color: var(--color-black);
|
--alternative-font-color: var(--color-black);
|
||||||
|
--alternative-backgrond-color: var(--light-background-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
* {
|
* {
|
||||||
@ -48,5 +49,6 @@ a {
|
|||||||
--light-font-color: var(--color-white);
|
--light-font-color: var(--color-white);
|
||||||
--dark-font-color: var(--color-white);
|
--dark-font-color: var(--color-white);
|
||||||
--alternative-font-color: var(--color-gray);
|
--alternative-font-color: var(--color-gray);
|
||||||
|
--alternative-backgrond-color: var(--color-black);
|
||||||
}
|
}
|
||||||
}
|
}
|
27
src/main.jsx
27
src/main.jsx
@ -4,8 +4,12 @@ import ReactDOM from 'react-dom/client'
|
|||||||
import { RouterProvider, createBrowserRouter } from 'react-router-dom'
|
import { RouterProvider, createBrowserRouter } from 'react-router-dom'
|
||||||
import ErrorPage from './pages/ErrorPage.jsx'
|
import ErrorPage from './pages/ErrorPage.jsx'
|
||||||
import FeedPage from './pages/FeedPage.jsx'
|
import FeedPage from './pages/FeedPage.jsx'
|
||||||
|
import UserProfilePage from './pages/UserProfilePage.jsx'
|
||||||
|
import ChatPage from './pages/ChatPage.jsx'
|
||||||
|
import FriendsPage from './pages/FriendsPage.jsx'
|
||||||
import App from './App.jsx'
|
import App from './App.jsx'
|
||||||
import './index.css'
|
import './index.css'
|
||||||
|
import { Person, LayoutTextSidebarReverse, ChatText, People } from 'react-bootstrap-icons';
|
||||||
|
|
||||||
const routes = [
|
const routes = [
|
||||||
{
|
{
|
||||||
@ -13,6 +17,29 @@ const routes = [
|
|||||||
path: '/',
|
path: '/',
|
||||||
element: <FeedPage />,
|
element: <FeedPage />,
|
||||||
title: 'Новости',
|
title: 'Новости',
|
||||||
|
menuIcon: <LayoutTextSidebarReverse />,
|
||||||
|
showInBottomMenu: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/me',
|
||||||
|
element: <UserProfilePage />,
|
||||||
|
title: 'Моя страница',
|
||||||
|
menuIcon: <Person />,
|
||||||
|
showInBottomMenu: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/chat',
|
||||||
|
element: <ChatPage />,
|
||||||
|
title: 'Сообщения',
|
||||||
|
menuIcon: <ChatText />,
|
||||||
|
showInBottomMenu: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/friends',
|
||||||
|
element: <FriendsPage />,
|
||||||
|
title: 'Друзья',
|
||||||
|
menuIcon: <People />,
|
||||||
|
showInBottomMenu: true
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
|
23
src/pages/ChatPage.jsx
Normal file
23
src/pages/ChatPage.jsx
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
import Wrapper from "../components/wrapper/wrapper";
|
||||||
|
import Center from "../components/center/center";
|
||||||
|
import ChatRow from "../components/chatrow/chatrow";
|
||||||
|
|
||||||
|
const ChatPage = () => {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Wrapper>
|
||||||
|
<Center>
|
||||||
|
<ChatRow />
|
||||||
|
<ChatRow />
|
||||||
|
<ChatRow />
|
||||||
|
<ChatRow />
|
||||||
|
<ChatRow />
|
||||||
|
<ChatRow />
|
||||||
|
<ChatRow />
|
||||||
|
</Center>
|
||||||
|
</Wrapper>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ChatPage;
|
@ -1,43 +1,26 @@
|
|||||||
import { Table } from 'react-bootstrap';
|
import Wrapper from "../components/wrapper/wrapper";
|
||||||
// import ulstuLogo from '../assets/logo.png';
|
import Center from "../components/center/center";
|
||||||
|
import PostInputForm from "../components/postinputform/postinputform";
|
||||||
|
import Post from "../components/post/post";
|
||||||
|
|
||||||
const Page2 = () => {
|
|
||||||
|
const FeedPage = () => {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<p className="text-center">
|
<Wrapper>
|
||||||
Вторая страница содержит пример рисунка (рис. 1) и таблицы (таб. 1).
|
<Center>
|
||||||
</p>
|
<PostInputForm />
|
||||||
<div className="text-center">
|
<div className="posts-wrapper">
|
||||||
{/* <img src={ulstuLogo} alt="logo" width="128" /> */}
|
<Post />
|
||||||
<br />
|
<Post />
|
||||||
Рис. 1. Пример рисунка.
|
<Post />
|
||||||
</div>
|
<Post />
|
||||||
<div className="mt-3 row justify-content-center">
|
<Post />
|
||||||
<Table className="w-50" bordered>
|
|
||||||
<caption>Таблица 1. Пример таблицы.</caption>
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th className="w-25">Номер</th>
|
|
||||||
<th>ФИО</th>
|
|
||||||
<th className="w-25">Телефон</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
<tr>
|
|
||||||
<td>1</td>
|
|
||||||
<td>Иванов</td>
|
|
||||||
<td>89999999999</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>2</td>
|
|
||||||
<td>Петров</td>
|
|
||||||
<td>89999999991</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</Table>
|
|
||||||
</div>
|
</div>
|
||||||
|
</Center>
|
||||||
|
</Wrapper>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default Page2;
|
export default FeedPage;
|
||||||
|
30
src/pages/FriendsPage.jsx
Normal file
30
src/pages/FriendsPage.jsx
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
import Wrapper from "../components/wrapper/wrapper";
|
||||||
|
import Center from "../components/center/center";
|
||||||
|
import { Search } from "react-bootstrap-icons";
|
||||||
|
import FriendRow from "../components/friendrow/friendrow";
|
||||||
|
|
||||||
|
const FriendsPage = () => {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Wrapper>
|
||||||
|
<Center>
|
||||||
|
<div className="input-group mb-3">
|
||||||
|
<input type="text" className="form-control" placeholder="Найти друзей" />
|
||||||
|
<button className="btn btn-outline-secondary" type="button" id="button-addon">
|
||||||
|
<Search />
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<FriendRow />
|
||||||
|
<FriendRow />
|
||||||
|
<FriendRow />
|
||||||
|
<FriendRow />
|
||||||
|
<FriendRow />
|
||||||
|
<FriendRow />
|
||||||
|
<FriendRow />
|
||||||
|
</Center>
|
||||||
|
</Wrapper>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default FriendsPage;
|
27
src/pages/UserProfilePage.jsx
Normal file
27
src/pages/UserProfilePage.jsx
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
import Wrapper from "../components/wrapper/wrapper";
|
||||||
|
import Center from "../components/center/center";
|
||||||
|
import PostInputForm from "../components/postinputform/postinputform";
|
||||||
|
import Post from "../components/post/post";
|
||||||
|
import UserProfileBlock from "../components/userprofileblock/userprofileblock";
|
||||||
|
|
||||||
|
const UserProfilePage = () => {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Wrapper>
|
||||||
|
<Center>
|
||||||
|
<UserProfileBlock />
|
||||||
|
<PostInputForm />
|
||||||
|
<div className="posts-wrapper">
|
||||||
|
<Post />
|
||||||
|
<Post />
|
||||||
|
<Post />
|
||||||
|
<Post />
|
||||||
|
<Post />
|
||||||
|
</div>
|
||||||
|
</Center>
|
||||||
|
</Wrapper>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default UserProfilePage;
|
Loading…
Reference in New Issue
Block a user