diff --git a/5 lab/src/assets/a.png b/5 lab/src/assets/a.png
new file mode 100644
index 0000000..54ae3b5
Binary files /dev/null and b/5 lab/src/assets/a.png differ
diff --git a/5 lab/src/assets/nick.png b/5 lab/src/assets/nick.png
new file mode 100644
index 0000000..18a9802
Binary files /dev/null and b/5 lab/src/assets/nick.png differ
diff --git a/5 lab/src/assets/p.png b/5 lab/src/assets/p.png
new file mode 100644
index 0000000..70fb362
Binary files /dev/null and b/5 lab/src/assets/p.png differ
diff --git a/5 lab/src/components/information/form/Info.jsx b/5 lab/src/components/information/form/Info.jsx
new file mode 100644
index 0000000..b00b40c
--- /dev/null
+++ b/5 lab/src/components/information/form/Info.jsx
@@ -0,0 +1,46 @@
+/* eslint-disable import/extensions */
+/* eslint-disable import/no-unresolved */
+import {
+ ListGroup, Modal, Button, Form,
+ } from 'react-bootstrap';
+import useLines from '../../users/hooks/UsersHook';
+import useLinesFormModal from '../hooks/HelpFormModalHook';
+import NickModal from './InfoModal';
+
+const InfoForm = () => {
+ const { handleLinesChange } = useLines();
+ const {
+ isFormModalShow,
+ isFormValidated,
+ showFormModal,
+ handleFormClose,
+ } = useLinesFormModal(handleLinesChange);
+ return (
+ <>
+
+
+
+ Информация
+
+
+ handleFormClose()}>
+
+ Информация
+
+
+
+ >
+ );
+};
+
+export default InfoForm;
diff --git a/5 lab/src/components/information/form/InfoModal.jsx b/5 lab/src/components/information/form/InfoModal.jsx
new file mode 100644
index 0000000..fa343a9
--- /dev/null
+++ b/5 lab/src/components/information/form/InfoModal.jsx
@@ -0,0 +1,18 @@
+import PropTypes from 'prop-types';
+
+const InfoModal = () => {
+ return (
+
+
Информация
+
Данный сделан специально для дисциплины интернет программирование
+
в 2023 году
+
+ );
+};
+
+InfoModal.propTypes = {
+ password: PropTypes.string,
+ setPassword: PropTypes.func,
+};
+
+export default InfoModal;
diff --git a/5 lab/src/components/information/hooks/HelpFormModalHook.js b/5 lab/src/components/information/hooks/HelpFormModalHook.js
new file mode 100644
index 0000000..720d5e1
--- /dev/null
+++ b/5 lab/src/components/information/hooks/HelpFormModalHook.js
@@ -0,0 +1,45 @@
+import { useState } from 'react';
+import useModal from '../../modal/ModalHook';
+import useLinesItemForm from '../../users/hooks/UsersItemFormHook';
+
+const useLinesFormModal = (linesChangeHandle, password) => {
+ const { isModalShow, showModal, hideModal } = useModal();
+ // eslint-disable-next-line no-unused-vars
+ const [currentId, setCurrentId] = useState(0);
+ const id = localStorage.getItem('UserId');
+ const {
+ item,
+ validated,
+ handleSubmitChange,
+ handleChange,
+ resetValidity,
+ } = useLinesItemForm(id, linesChangeHandle);
+
+ const showModalDialog = (ids) => {
+ setCurrentId(ids);
+ resetValidity();
+ showModal();
+ };
+
+ const onClose = () => {
+ setCurrentId(-1);
+ hideModal();
+ };
+
+ const onSubmit = async (event) => {
+ if (await handleSubmitChange(event, 'password', password)) {
+ onClose();
+ }
+ };
+ return {
+ isFormModalShow: isModalShow,
+ isFormValidated: validated,
+ showFormModal: showModalDialog,
+ currentItem: item,
+ handleItemChange: handleChange,
+ handleFormSubmit: onSubmit,
+ handleFormClose: onClose,
+ };
+};
+
+export default useLinesFormModal;
diff --git a/5 lab/src/components/messages/form/MessagesForm.jsx b/5 lab/src/components/messages/form/MessagesForm.jsx
new file mode 100644
index 0000000..aefeda4
--- /dev/null
+++ b/5 lab/src/components/messages/form/MessagesForm.jsx
@@ -0,0 +1,33 @@
+import PropTypes from 'prop-types';
+import { Form } from 'react-bootstrap';
+import useLinesItemForm from '../hooks/MessagesItemFormHook';
+import LinesItemForm from './MessagesItemForm.jsx';
+
+const LinesForm = ({ id, messages }) => {
+ const {
+ validated,
+ } = useLinesItemForm(id);
+ const { message } = messages;
+ if (message !== undefined) {
+ return (
+ <>
+
+ >
+ );
+ // eslint-disable-next-line no-else-return
+ } else {
+ return (<>>);
+ }
+};
+
+LinesForm.propTypes = {
+ id: PropTypes.number,
+ messages: PropTypes.object,
+};
+
+export default LinesForm;
diff --git a/5 lab/src/components/messages/form/MessagesItemForm.jsx b/5 lab/src/components/messages/form/MessagesItemForm.jsx
new file mode 100644
index 0000000..2768322
--- /dev/null
+++ b/5 lab/src/components/messages/form/MessagesItemForm.jsx
@@ -0,0 +1,26 @@
+import PropTypes from 'prop-types';
+
+const LinesItemForm = ({ item }) => {
+ let cl;
+ // eslint-disable-next-line eqeqeq
+ if (item.senderId == localStorage.getItem('UserId')) {
+ cl = 'd-flex align-items-end flex-column gap-3';
+ } else {
+ cl = 'd-flex align-items-start flex-column gap-3';
+ }
+ return (
+
+
+
{item.msg}
+
{item.time}
+
+
+ );
+};
+
+LinesItemForm.propTypes = {
+ item: PropTypes.object,
+ handleChange: PropTypes.func,
+};
+
+export default LinesItemForm;
diff --git a/5 lab/src/components/messages/hooks/MessagesHook.js b/5 lab/src/components/messages/hooks/MessagesHook.js
new file mode 100644
index 0000000..2583a87
--- /dev/null
+++ b/5 lab/src/components/messages/hooks/MessagesHook.js
@@ -0,0 +1,29 @@
+import { useEffect, useState } from 'react';
+import LinesApiService from '../service/MessagesApiService';
+
+const useLines = (typeFilter) => {
+ const [linesRefresh, setLinesRefresh] = useState(false);
+ const [messages, setLines] = useState([]);
+ const handleLinesChange = () => setLinesRefresh(!linesRefresh);
+
+ const getLines = async () => {
+ let expand = '';
+ if (typeFilter) {
+ expand = `?groupId=${typeFilter}`;
+ }
+ const data = await LinesApiService.getAll(expand);
+ setLines(data ?? []);
+ };
+
+ useEffect(() => {
+ getLines();
+ // eslint-disable-next-line react-hooks/exhaustive-deps
+ }, [linesRefresh, typeFilter]);
+
+ return {
+ messages,
+ handleLinesChange,
+ };
+};
+
+export default useLines;
diff --git a/5 lab/src/components/messages/hooks/MessagesItemFormHook.js b/5 lab/src/components/messages/hooks/MessagesItemFormHook.js
new file mode 100644
index 0000000..364367f
--- /dev/null
+++ b/5 lab/src/components/messages/hooks/MessagesItemFormHook.js
@@ -0,0 +1,56 @@
+import { useState } from 'react';
+import toast from 'react-hot-toast';
+import LinesApiService from '../service/MessagesApiService';
+import useLinesItem from './MessagesItemHook';
+import useLines from './MessagesHook';
+
+const useLinesItemForm = (id, linesChangeHandle) => {
+ const { item } = useLinesItem(id);
+ const tmp = useLines();
+ const ids = tmp.messages.length + 1;
+ const { messages } = useLines(id);
+ const [validated, setValidated] = useState(false);
+ const resetValidity = () => {
+ setValidated(false);
+ };
+
+ const getLineObject = (formData, text, groupID) => {
+ const groupId = groupID.toString();
+ const senderId = localStorage.getItem('UserId').toString();
+ const msg = text.toString();
+ const time = `${new Date().toLocaleDateString()} ${new Date().toLocaleTimeString()}`;
+ return {
+ groupId: groupId.toString(),
+ senderId: senderId.toString(),
+ msg: msg.toString(),
+ time: time.toString(),
+ };
+ };
+
+ const handleSubmit = async (event, text, groupId, setMessages) => {
+ const form = event.currentTarget;
+ event.preventDefault();
+ event.stopPropagation();
+ const body = getLineObject(item, text, groupId);
+ if (form.checkValidity()) {
+ await LinesApiService.create(body);
+ body.id = ids;
+ messages.push(body);
+ setMessages({ message: messages });
+ if (linesChangeHandle) linesChangeHandle();
+ toast.success('Элемент успешно сохранен', { id: 'LinesTable' });
+ return true;
+ }
+ setValidated(true);
+ return false;
+ };
+
+ return {
+ item,
+ validated,
+ handleSubmit,
+ resetValidity,
+ };
+};
+
+export default useLinesItemForm;
diff --git a/5 lab/src/components/messages/hooks/MessagesItemHook.js b/5 lab/src/components/messages/hooks/MessagesItemHook.js
new file mode 100644
index 0000000..35e02b0
--- /dev/null
+++ b/5 lab/src/components/messages/hooks/MessagesItemHook.js
@@ -0,0 +1,38 @@
+import { useEffect, useState } from 'react';
+import LinesApiService from '../service/MessagesApiService';
+
+const useLinesItem = (id) => {
+ const emptyItem = {
+ groupId: '',
+ groupMessages: [
+ {
+ id: '',
+ senderId: '',
+ recieverId: '',
+ msg: '',
+ },
+ ],
+ };
+ const [item, setItem] = useState({ ...emptyItem });
+
+ const getItem = async (itemId = undefined) => {
+ if (itemId && itemId > 0) {
+ const data = await LinesApiService.get(itemId);
+ setItem(data);
+ } else {
+ setItem({ ...emptyItem });
+ }
+ };
+
+ useEffect(() => {
+ getItem(id);
+ // eslint-disable-next-line react-hooks/exhaustive-deps
+ }, [id]);
+
+ return {
+ item,
+ setItem,
+ };
+};
+
+export default useLinesItem;
diff --git a/5 lab/src/components/messages/service/MessagesApiService.js b/5 lab/src/components/messages/service/MessagesApiService.js
new file mode 100644
index 0000000..a289b82
--- /dev/null
+++ b/5 lab/src/components/messages/service/MessagesApiService.js
@@ -0,0 +1,5 @@
+import ApiService from '../../api/ApiService';
+
+const LinesApiService = new ApiService('messages');
+
+export default LinesApiService;
diff --git a/5 lab/src/components/messages/table/Line.jsx b/5 lab/src/components/messages/table/Line.jsx
new file mode 100644
index 0000000..b260198
--- /dev/null
+++ b/5 lab/src/components/messages/table/Line.jsx
@@ -0,0 +1,38 @@
+import PropTypes from 'prop-types';
+import useLines from '../../users/hooks/UsersHook';
+
+const Line = ({
+ index, personId, friendId,
+}) => {
+ const { users } = useLines();
+ let personNickname = null;
+ users.map((line) => {
+ if (line.id === personId) {
+ personNickname = line.nickname;
+ return '';
+ }
+ return '';
+ });
+ let friendNickname = null;
+ users.map((line) => {
+ if (line.id === friendId) {
+ friendNickname = line.nickname;
+ return '';
+ }
+ return '';
+ });
+ return (
+
+ {index + 1} |
+ {personNickname} |
+ {friendNickname} |
+
+ );
+};
+Line.propTypes = {
+ index: PropTypes.number,
+ personId: PropTypes.number,
+ friendId: PropTypes.number,
+ users: PropTypes.object,
+};
+export default Line;
diff --git a/5 lab/src/components/messages/table/LinesTable.jsx b/5 lab/src/components/messages/table/LinesTable.jsx
new file mode 100644
index 0000000..bd721e7
--- /dev/null
+++ b/5 lab/src/components/messages/table/LinesTable.jsx
@@ -0,0 +1,30 @@
+import PropTypes from 'prop-types';
+import { Table } from 'react-bootstrap';
+
+const LinesTable = ({ children }) => {
+ return (
+
+
+
+ № |
+ id человека |
+ друг |
+ |
+ |
+ |
+ |
+ |
+
+
+
+ {children}
+
+
+ );
+};
+
+LinesTable.propTypes = {
+ children: PropTypes.node,
+};
+
+export default LinesTable;
diff --git a/5 lab/src/components/messages/table/LinesTableRow.jsx b/5 lab/src/components/messages/table/LinesTableRow.jsx
new file mode 100644
index 0000000..413232f
--- /dev/null
+++ b/5 lab/src/components/messages/table/LinesTableRow.jsx
@@ -0,0 +1,24 @@
+import PropTypes from 'prop-types';
+
+const LinesTableRow = ({
+ index, line,
+}) => {
+ return (
+
+ {index + 1} |
+ {line.personId} |
+ {line.friend} |
+ {line.nickname} |
+
+ );
+};
+
+LinesTableRow.propTypes = {
+ index: PropTypes.number,
+ line: PropTypes.object,
+ onDelete: PropTypes.func,
+ onEdit: PropTypes.func,
+ onEditInPage: PropTypes.func,
+};
+
+export default LinesTableRow;
diff --git a/Отчеты/Otchet5_IP_Razubaev_PIbd-21.odt b/Отчеты/Otchet5_IP_Razubaev_PIbd-21.odt
new file mode 100644
index 0000000..8b3f2bd
Binary files /dev/null and b/Отчеты/Otchet5_IP_Razubaev_PIbd-21.odt differ