From e7d8652ac0c93124c21e504afc958531afcafd0e Mon Sep 17 00:00:00 2001 From: test Date: Thu, 26 Jun 2025 17:31:34 +0500 Subject: [PATCH] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D0=B5=20=D0=BF=D0=B5=D1=80=D0=B5=D0=BA=D0=BB=D1=8E?= =?UTF-8?q?=D1=87=D0=B5=D0=BD=D0=B8=D1=8F=20DCHP?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FRONT/DEV/src/components/UI/Pagination.tsx | 24 +++++-- .../nodes/networkInterface/ipNode/ipNode.tsx | 24 ++++++- .../modalContainers/SettingItem.tsx | 47 ++++++++++++ .../modalwindows/modalContainers/Settings.tsx | 72 +++++++++++++++++++ .../modalContainers/ipConfirm.tsx | 2 +- .../components/modalwindows/modalWindow.tsx | 6 ++ .../DEV/src/components/modalwindows/style.ts | 4 +- .../usersScanner/modules}/TableScanner.tsx | 32 +++++---- .../usersScanner/modules/TableUsers.tsx | 2 +- .../workSpace/sideBar/toolBar/toolBar.tsx | 5 ++ FRONT/DEV/src/const/buttons/icons.tsx | 2 + FRONT/DEV/src/const/buttons/names.ts | 1 + FRONT/DEV/src/store/settingsStore.ts | 46 ++++++++++++ 13 files changed, 241 insertions(+), 26 deletions(-) create mode 100644 FRONT/DEV/src/components/modalwindows/modalContainers/SettingItem.tsx create mode 100644 FRONT/DEV/src/components/modalwindows/modalContainers/Settings.tsx rename FRONT/DEV/src/components/{UI/tables => workSpace/modules/appModules/usersScanner/modules}/TableScanner.tsx (82%) create mode 100644 FRONT/DEV/src/store/settingsStore.ts diff --git a/FRONT/DEV/src/components/UI/Pagination.tsx b/FRONT/DEV/src/components/UI/Pagination.tsx index 94e63d8..08ed767 100644 --- a/FRONT/DEV/src/components/UI/Pagination.tsx +++ b/FRONT/DEV/src/components/UI/Pagination.tsx @@ -11,11 +11,11 @@ const PaginateWrapper = styled.div` align-items: center; gap: 10px; ` -const Page = styled.button` +const Page = styled.button<{ active?: boolean }>` width: 36px; height: 36px; - background: ${(props => props.theme.primary)}; - color: ${(props => props.theme.textColor)}; + background: ${(props) => props.active ? props.theme.borderColor : props.theme.primary}; + color: ${(props) => props.active ? props.theme.primary : props.theme.textColor}; border: 1px solid ${(props => props.theme.borderColor)}; font-size: 16px; cursor: pointer; @@ -23,7 +23,7 @@ const Page = styled.button` transition: .4s ease; &:hover { - background: ${(props => props.theme.background)}; + background: ${(props) => props.active ? props.theme.textColor : props.theme.background};; } ` @@ -32,9 +32,13 @@ interface PaginationProps { totalPages: number; onPrevPage: () => void; onNextPage: () => void; + onPageChange: (page: number) => void; } -const Pagination = ({currentPage, totalPages, onPrevPage, onNextPage}: PaginationProps) => { +const Pagination = ({currentPage, totalPages, onPrevPage, onNextPage, onPageChange}: PaginationProps) => { + + const pageNumbers = Array.from({ length: totalPages }, (_, i) => i + 1); + return ( - + {pageNumbers.map((page, i) => ( + onPageChange(page)} + active={currentPage === page} + > + {page} + + ))} { const { toggleEditingMode } = usePannableStore(); const [isInput, setIsInput] = useState(false) const { openModal } = useModalContext(); + const {ipAddress} = useIpStore(); const [ipData, setIpData] = useState( { @@ -146,7 +148,20 @@ export const IpNode = ({ data }: CustomNodeProps) => { setIsInput(false) }; - + const switchMethod = async ()=>{ + const methodDCHP ={ + "connection_id": ipData.connection, + "ipv4_updates": { + "ipv4.method": "auto", + } + } + try { + await NetworkService.saveIp(ipAddress, methodDCHP); + window.location.reload(); + }catch (err){ + console.error(err) + } + } return ( <> @@ -170,7 +185,10 @@ export const IpNode = ({ data }: CustomNodeProps) => { ) : ( - + + {typeMap[data.ipData.ipType] ==='Static' && } + + )} diff --git a/FRONT/DEV/src/components/modalwindows/modalContainers/SettingItem.tsx b/FRONT/DEV/src/components/modalwindows/modalContainers/SettingItem.tsx new file mode 100644 index 0000000..f2252f0 --- /dev/null +++ b/FRONT/DEV/src/components/modalwindows/modalContainers/SettingItem.tsx @@ -0,0 +1,47 @@ +import { useSettingsStore } from '../stores/settingsStore'; + +export const SettingItem = ({ setting }: { setting: Setting }) => { + const { updateSetting } = useSettingsStore(); + + const handleChange = ( + e: React.ChangeEvent + ) => { + const value = + setting.type === 'boolean' + ? (e.target as HTMLInputElement).checked + : e.target.value; + updateSetting(setting.id, value); + }; + + return ( +
+ + + {setting.type === 'boolean' && ( + + )} + + {setting.type === 'select' && setting.options && ( + + )} + + {setting.type === 'text' && ( + + )} +
+ ); +}; \ No newline at end of file diff --git a/FRONT/DEV/src/components/modalwindows/modalContainers/Settings.tsx b/FRONT/DEV/src/components/modalwindows/modalContainers/Settings.tsx new file mode 100644 index 0000000..d43a11d --- /dev/null +++ b/FRONT/DEV/src/components/modalwindows/modalContainers/Settings.tsx @@ -0,0 +1,72 @@ +// components/modalContainers/NoteDevice.tsx +import { ModalContainer, ModalTitle, ModalContent, ButtonContainer } from "../style"; +import { MainButton } from "../../UI/buttons/mainButton"; +import {useEffect, useState} from "react"; +import styled from "styled-components"; +import { useSettingsStore } from "../../../store/settingsStore"; + +interface Props { + onClose: () => void; +} + +const SectionsSidebar = styled.div` + display: flex; + justify-content: start; + align-items: start; + flex-direction: column; + gap: 12px; + width: 20%; + +` +const SectionsBTN = styled.button` + font-size: 18px; + border: none; + cursor: pointer; +` +const SectionActive = styled.div` + width: 80%; + background-color: red; +` + +const sections = [ + {id: 'nodesNetwork', label: 'Узлы подсети'}, + {id: 'wifiNetwork', label: 'Точки доступа'}, + {id: 'appearance', label: 'Внешний вид'}, +] + + +export const Settings = ({onClose}: Props) => { + const {activeSection, setActiveSection, initializeSettings} = useSettingsStore(); + + useEffect(() => { + initializeSettings(); + }, [initializeSettings]); + + return ( + + +

Настройки

+
+ + + + {sections.map((section) => ( + {section.label} + ))} + + + {activeSection && } + + + + + + +
+ ); +}; \ No newline at end of file diff --git a/FRONT/DEV/src/components/modalwindows/modalContainers/ipConfirm.tsx b/FRONT/DEV/src/components/modalwindows/modalContainers/ipConfirm.tsx index 2e2b998..2b2a334 100644 --- a/FRONT/DEV/src/components/modalwindows/modalContainers/ipConfirm.tsx +++ b/FRONT/DEV/src/components/modalwindows/modalContainers/ipConfirm.tsx @@ -120,7 +120,7 @@ export const IpConfirm = ({ ipData, onClose, smoothClose }: Props) => { ); useDevicesStore.setState({ devices: updatedDevices }); } - + onClose() } } catch (err) { diff --git a/FRONT/DEV/src/components/modalwindows/modalWindow.tsx b/FRONT/DEV/src/components/modalwindows/modalWindow.tsx index 7edf179..487372c 100644 --- a/FRONT/DEV/src/components/modalwindows/modalWindow.tsx +++ b/FRONT/DEV/src/components/modalwindows/modalWindow.tsx @@ -7,6 +7,7 @@ import {NoteDevice} from "./modalContainers/NoteDevice"; import { NoteWifi } from "./modalContainers/NoteWifi"; import {ConnectNetwork} from "./modalContainers/ConnectNetwork"; import {DisconnectConfirm} from "./modalContainers/disconnectConfirm"; +import {Settings} from "./modalContainers/Settings"; type Props = { isOpen: boolean, @@ -74,6 +75,11 @@ export default function WindowComponent({ isOpen, type, data }: Props) { {type === ModalMap['5'] && ( )} + {type === ModalMap['10'] && ( + + )} } diff --git a/FRONT/DEV/src/components/modalwindows/style.ts b/FRONT/DEV/src/components/modalwindows/style.ts index 2b75bd3..2e588c2 100644 --- a/FRONT/DEV/src/components/modalwindows/style.ts +++ b/FRONT/DEV/src/components/modalwindows/style.ts @@ -13,7 +13,7 @@ export const ModalWindow = styled.div` height: 100%; ` -export const ModalContainer = styled.div<{height?: string}>` +export const ModalContainer = styled.div<{height?: string, width?:string}>` border-radius: 12px; background: ${(props)=>props.theme.secondary}; color: ${(props=>props.theme.textColor)}; @@ -25,7 +25,7 @@ export const ModalContainer = styled.div<{height?: string}>` justify-content: space-between; gap: 15px; height: ${(props) => props.height ? props.height : '230px'}; - width: 520px; + width: ${(props) => props.width ? props.width : '520px'}; ` export const ModalTitle = styled.div` diff --git a/FRONT/DEV/src/components/UI/tables/TableScanner.tsx b/FRONT/DEV/src/components/workSpace/modules/appModules/usersScanner/modules/TableScanner.tsx similarity index 82% rename from FRONT/DEV/src/components/UI/tables/TableScanner.tsx rename to FRONT/DEV/src/components/workSpace/modules/appModules/usersScanner/modules/TableScanner.tsx index 8657a17..0689756 100644 --- a/FRONT/DEV/src/components/UI/tables/TableScanner.tsx +++ b/FRONT/DEV/src/components/workSpace/modules/appModules/usersScanner/modules/TableScanner.tsx @@ -1,15 +1,15 @@ import React, {useState} from 'react'; -import { DeviceUser } from '../../../store/useDeviceStore'; +import { DeviceUser } from '../../../../../../store/useDeviceStore'; interface TableScannerProps { devices: DeviceUser[]; } import styled from 'styled-components'; -import {IconComponent} from "../../../const/buttons/icons"; -import {buttonNames} from "../../../const/buttons/names"; -import {ModalMap} from "../../modalwindows/windowsType"; -import {useModalContext} from "../../../store"; -import Pagination from "../Pagination"; +import {IconComponent} from "../../../../../../const/buttons/icons"; +import {buttonNames} from "../../../../../../const/buttons/names"; +import {ModalMap} from "../../../../../modalwindows/windowsType"; +import {useModalContext} from "../../../../../../store"; +import Pagination from "../../../../../UI/Pagination"; const TableContainer = styled.div` width: 100%; @@ -76,7 +76,7 @@ const TableScanner = ({devices}:TableScannerProps) => { // Пагинация const [currentPage, setCurrentPage] = useState(1); - const [devicesPerPage] = useState(10); + const [devicesPerPage] = useState(15); const indexOfLastDevice = currentPage * devicesPerPage; const indexOfFirstDevice = indexOfLastDevice - devicesPerPage; @@ -89,6 +89,9 @@ const TableScanner = ({devices}:TableScannerProps) => { const handleNextPage = () => { if(currentPage < totalPages) setCurrentPage(currentPage + 1); } + const onPageChange = (page: number) => { + setCurrentPage(page); + } return ( @@ -124,12 +127,15 @@ const TableScanner = ({devices}:TableScannerProps) => { ))} - + {totalPages > 1 && ( + + )} ); }; diff --git a/FRONT/DEV/src/components/workSpace/modules/appModules/usersScanner/modules/TableUsers.tsx b/FRONT/DEV/src/components/workSpace/modules/appModules/usersScanner/modules/TableUsers.tsx index 77e064c..53f7773 100644 --- a/FRONT/DEV/src/components/workSpace/modules/appModules/usersScanner/modules/TableUsers.tsx +++ b/FRONT/DEV/src/components/workSpace/modules/appModules/usersScanner/modules/TableUsers.tsx @@ -2,7 +2,7 @@ import React from 'react'; import styled from 'styled-components'; import DeviceCard from "../../../../../UI/Dropdown/DeviceCard"; import {DeviceUser} from "../../../../../../store/useDeviceStore"; -import TableScanner from "../../../../../UI/tables/TableScanner"; +import TableScanner from "./TableScanner"; const ScanBtn = styled.button` position: relative; diff --git a/FRONT/DEV/src/components/workSpace/sideBar/toolBar/toolBar.tsx b/FRONT/DEV/src/components/workSpace/sideBar/toolBar/toolBar.tsx index 9fd05a2..1f49b9c 100644 --- a/FRONT/DEV/src/components/workSpace/sideBar/toolBar/toolBar.tsx +++ b/FRONT/DEV/src/components/workSpace/sideBar/toolBar/toolBar.tsx @@ -81,6 +81,11 @@ export const ToolBar = () => { /> + ) diff --git a/FRONT/DEV/src/const/buttons/icons.tsx b/FRONT/DEV/src/const/buttons/icons.tsx index 9cab629..db08c85 100644 --- a/FRONT/DEV/src/const/buttons/icons.tsx +++ b/FRONT/DEV/src/const/buttons/icons.tsx @@ -20,6 +20,7 @@ import refresh from '@iconify/icons-ic/baseline-refresh'; import close from '@iconify/icons-ic/round-close'; import wifiFind from '@iconify/icons-ic/baseline-wifi-find'; import noteEdit from '@iconify/icons-ph/note-pencil'; +import swapHoriz from '@iconify/icons-ic/baseline-swap-horiz'; export const ICONS = { [buttonNames[1]]: exitToApp, @@ -39,6 +40,7 @@ export const ICONS = { [buttonNames[15]]: wifiFind, [buttonNames[16]]: noteEdit, [buttonNames[17]]: arrowLeft, + [buttonNames[18]]: swapHoriz, } as const; type IconName = keyof typeof ICONS; diff --git a/FRONT/DEV/src/const/buttons/names.ts b/FRONT/DEV/src/const/buttons/names.ts index 052321e..f933de5 100644 --- a/FRONT/DEV/src/const/buttons/names.ts +++ b/FRONT/DEV/src/const/buttons/names.ts @@ -18,4 +18,5 @@ export const buttonNames: names ={ 15: 'wifiFind', 16: 'noteEdit', 17: 'arrowLeft', + 18: 'swapHoriz', } \ No newline at end of file diff --git a/FRONT/DEV/src/store/settingsStore.ts b/FRONT/DEV/src/store/settingsStore.ts new file mode 100644 index 0000000..b4a72d1 --- /dev/null +++ b/FRONT/DEV/src/store/settingsStore.ts @@ -0,0 +1,46 @@ +import { create } from 'zustand'; + +export type Setting = { + id: string; + type: 'boolean' | 'select' | 'text' | 'number'; + label: string; + value: any; + options?: { value: any; label: string }[]; + sectionId: string; +}; + +type SettingsState = { + settings: Setting[]; + activeSection: string | null; + setActiveSection: (sectionId: string | null) => void; + updateSetting: (id: string, value: any) => void; + initializeSettings: () => void; +}; + +export const useSettingsStore = create((set) => ({ + settings: [], + activeSection: null, + + setActiveSection: (sectionId) => set({ activeSection: sectionId }), + + updateSetting: (id, value) => + set((state) => ({ + settings: state.settings.map((setting) => + setting.id === id ? { ...setting, value } : setting + ), + })), + + initializeSettings: () => { + const defaultSettings: Setting[] = [ + { + id: 'rescan-nodes', + type: 'number', + label: 'nodesNetwork', + value: 3000, + sectionId: 'appearance', + }, + + ]; + set({ settings: defaultSettings }); + }, +})); \ No newline at end of file