diff --git a/src/app/[locale]/pages/layout.tsx b/src/app/[locale]/pages/layout.tsx index 63a3d19..23866bb 100644 --- a/src/app/[locale]/pages/layout.tsx +++ b/src/app/[locale]/pages/layout.tsx @@ -1,4 +1,4 @@ -import NavLinks from '@/app/ui/nav-links' +import NavLinks from '@/app/ui/navigation/nav-links' import HeaderPanel from '@/app/ui/header/headerPanel'; import { getQueryClient } from '@/app/providers/getQueryClient'; import { HydrationBoundary, dehydrate } from '@tanstack/react-query'; diff --git a/src/app/[locale]/pages/violations/page.tsx b/src/app/[locale]/pages/violations/page.tsx index 3e83132..43d58a8 100644 --- a/src/app/[locale]/pages/violations/page.tsx +++ b/src/app/[locale]/pages/violations/page.tsx @@ -18,7 +18,7 @@ export default function Page() { -
+
diff --git a/src/app/components/LanguageSwitcher.tsx b/src/app/components/LanguageSwitcher.tsx index ad54b73..a711120 100644 --- a/src/app/components/LanguageSwitcher.tsx +++ b/src/app/components/LanguageSwitcher.tsx @@ -44,9 +44,13 @@ export default function LanguageSwitcher() { }, 3000) } - useClickOutside(dropdownRef, () => { - setIsOpen(false); - }); + useClickOutside( + dropdownRef, + () => { + setIsOpen(false); + }, + isOpen + ); useEffect(() => { const handleEscape = (event: KeyboardEvent) => { diff --git a/src/app/components/dropDownList.tsx b/src/app/components/dropDownList.tsx index d242d6b..ffcdd19 100644 --- a/src/app/components/dropDownList.tsx +++ b/src/app/components/dropDownList.tsx @@ -18,9 +18,12 @@ interface ChildProps { export default function DropDownList({ children, value, callBack, translatedValue }: DropDownListProps) { const [isOpen, setIsOpen] = useState(false) const dropdownRef = useRef(null) - useClickOutside(dropdownRef, () => { - setIsOpen(false); - }); + useClickOutside(dropdownRef, + () => { + setIsOpen(false); + }, + isOpen + ); const enhancedChildren = React.Children.map(children, (child, index) => { if (React.isValidElement(child)) { diff --git a/src/app/hooks/useClickOutside.tsx b/src/app/hooks/useClickOutside.tsx index afa2271..9d8b283 100644 --- a/src/app/hooks/useClickOutside.tsx +++ b/src/app/hooks/useClickOutside.tsx @@ -4,14 +4,17 @@ import { useEffect, RefObject } from 'react'; export function useClickOutside( ref: RefObject, - callback: () => void + callback: () => void, + isActive: boolean = true ) { useEffect(() => { + if (!isActive) return; + const handleClick = (event: MouseEvent) => { - if (!ref) { + if (!ref?.current) { return; } - if (ref.current && !ref.current.contains(event.target as Node)) { + if (!ref.current.contains(event.target as Node)) { callback(); } }; @@ -20,5 +23,5 @@ export function useClickOutside( return () => { document.removeEventListener('mousedown', handleClick); }; - }, [ref, callback]); + }, [ref, callback, isActive]); } \ No newline at end of file diff --git a/src/app/stores/sideMenuStore.ts b/src/app/stores/sideMenuStore.ts new file mode 100644 index 0000000..ac2a0e5 --- /dev/null +++ b/src/app/stores/sideMenuStore.ts @@ -0,0 +1,19 @@ +import { create } from 'zustand' + +interface Store { + value: boolean + setValue: (value: boolean) => void +} + +export const useSideMenuStore = create()( + (set) => ({ + value: false, + setValue: (value) => { + set({ value: value }) + } + }) +) + +/* пример */ +/* const setMenuState = useSideMenuStore(s => s.setValue); */ +/* const menuState = useSideMenuStore(s => s.value); */ \ No newline at end of file diff --git a/src/app/styles/global-styles.scss b/src/app/styles/global-styles.scss index d67eab1..c2f5c4b 100644 --- a/src/app/styles/global-styles.scss +++ b/src/app/styles/global-styles.scss @@ -39,6 +39,7 @@ margin-bottom: 2rem; box-shadow: 0 10px 40px rgba(102, 126, 234, 0.2); color: v.$white; + max-width: calc(100vw - var(--side-bar-width) - 60px); h1 { font-size: 2rem; @@ -60,6 +61,10 @@ align-items: center; gap: 40px; + @media (max-width: 700px) { + flex-direction: column; + } + .header-main { flex: 1; } @@ -243,7 +248,6 @@ } .sidebar { - /* width: v.$side-bar-width; */ width: var(--side-bar-width); background: linear-gradient(180deg, v.$p-color 0%, v.$s-color 100%); padding: 30px 0; @@ -252,6 +256,41 @@ overflow-y: auto; z-index: 100; border-radius: 0 30px 30px 0; + transition: transform 0.3s ease-in-out; + transform: translateX(-100%); + + @media (max-width: 767px) { + width: 400px; + display: block; + + &.show { + transform: translateX(0); + } + + &:not(.show) { + transform: translateX(-100%); + } + } + + @media (max-width: 400px) { + width: 100%; + } + + @media (min-width: 767px) { + width: var(--side-bar-width); + transform: translateX(0); + } +} + +.sidebar-close-button { + padding: 0 15px 20px; + color: v.$white; + cursor: pointer; + display: none; + + @media (max-width: 767px) { + display: block; + } } .nav-link { @@ -427,6 +466,10 @@ &:focus { outline: none; } + + @media (max-width: 490px) { + padding: 0.5rem 8px; + } } .switcher-list { diff --git a/src/app/styles/header.scss b/src/app/styles/header.scss index 2f608e7..e534826 100644 --- a/src/app/styles/header.scss +++ b/src/app/styles/header.scss @@ -10,6 +10,10 @@ border-radius: 20px; box-shadow: 0 4px 20px v.$shadow-1; + @media (max-width: 490px) { + padding: 20px 20px; + } + .header-action { display: flex; align-items: center; @@ -60,6 +64,10 @@ font-size: 12px; font-weight: 600; min-width: 110px; + + @media (max-width: 490px) { + padding: 8px; + } } .tokens-count { @@ -289,4 +297,15 @@ } } } + + .header-burger-menu { + display: none; + margin-right: auto; + cursor: pointer; + color: v.$p-color; + + @media (max-width: 767px) { + display: block; + } + } } \ No newline at end of file diff --git a/src/app/styles/pages-styles.scss b/src/app/styles/pages-styles.scss index a5f566a..8adc088 100644 --- a/src/app/styles/pages-styles.scss +++ b/src/app/styles/pages-styles.scss @@ -235,6 +235,7 @@ grid-template-columns: repeat(5, 1fr); border-bottom: 1px solid v.$b-color-1; align-items: center; + overflow: auto; .stats-item { border: 1px solid v.$b-color-1; @@ -930,6 +931,15 @@ grid-template-columns: repeat(5, 1fr); gap: 16px; margin-bottom: 24px; + max-width: calc(100vw - var(--side-bar-width) - 60px); + + @media (max-width: 960px) { + grid-template-columns: repeat(2, 1fr); + } + + @media (max-width: 670px) { + grid-template-columns: auto; + } .stat-card { background: white; @@ -996,6 +1006,7 @@ box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1); margin-bottom: 30px; text-align: center; + max-width: calc(100vw - var(--side-bar-width) - 60px); .referral-link-input { display: flex; @@ -1003,6 +1014,11 @@ max-width: 700px; margin: 20px auto; + @media (max-width: 890px) { + flex-wrap: wrap; + justify-content: center; + } + #referral-link { display: flex; flex: 1; @@ -1066,6 +1082,14 @@ gap: 20px; margin-top: 20px; + @media (max-width: 960px) { + grid-template-columns: repeat(2, 1fr); + } + + @media (max-width: 540px) { + grid-template-columns: auto; + } + .level-card { background: linear-gradient(135deg, #f8f9fa 0%, #ffffff 100%); border: 2px solid #e2e8f0; @@ -1193,6 +1217,15 @@ align-items: end; margin-top: 15px; + @media (max-width: 880px) { + flex-direction: column; + align-items: center; + + .form-group { + width: 100%; + } + } + .form-group { flex: 1; margin-bottom: 0; @@ -2108,6 +2141,7 @@ grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 1.5rem; margin-bottom: 2rem; + max-width: calc(100vw - var(--side-bar-width) - 60px); &-stat-card { background: white; @@ -2226,6 +2260,7 @@ padding: 32px; margin-bottom: 24px; box-shadow: 0 10px 40px rgba(99, 102, 241, 0.1); + max-width: calc(100vw - var(--side-bar-width) - 60px); .my-cases-header { display: flex; @@ -2268,6 +2303,10 @@ grid-template-columns: repeat(3, 1fr); gap: 20px; + @media (max-width: 890px) { + grid-template-columns: auto; + } + .case-card { background: linear-gradient(135deg, #ffffff 0%, #f8f9fa 100%); border: 2px solid #e2e8f0; @@ -2378,6 +2417,7 @@ align-items: center; justify-content: space-between; gap: 24px; + max-width: calc(100vw - var(--side-bar-width) - 60px); .check-all-left { flex: 1; @@ -2432,6 +2472,7 @@ .violations-table-section { margin-bottom: 24px; + max-width: calc(100vw - var(--side-bar-width) - 60px); .section-header { display: flex; @@ -2464,6 +2505,7 @@ overflow: hidden; box-shadow: 0 4px 6px rgba(0, 0, 0, 0.05); border: 2px solid #e2e8f0; + overflow: auto; .violations-table { width: 100%; diff --git a/src/app/styles/variable.scss b/src/app/styles/variable.scss index fc22098..24d51fb 100644 --- a/src/app/styles/variable.scss +++ b/src/app/styles/variable.scss @@ -24,4 +24,8 @@ $color-document: #a561e6; @media (max-width: 1200px) { --side-bar-width: 180px; } + + @media (max-width: 767px) { + --side-bar-width: 0px; + } } \ No newline at end of file diff --git a/src/app/ui/dashboard/protection-overview.tsx b/src/app/ui/dashboard/protection-overview.tsx index 6441268..93b0d47 100644 --- a/src/app/ui/dashboard/protection-overview.tsx +++ b/src/app/ui/dashboard/protection-overview.tsx @@ -2,7 +2,7 @@ import { useState, useRef, useEffect } from 'react'; import { PieChartComponent } from '@/app/components/PieChartComponent'; -import {useTranslations, useLocale} from 'next-intl'; +import { useTranslations, useLocale } from 'next-intl'; import Link from 'next/link'; import { useClickOutside } from '@/app/hooks/useClickOutside'; import { useQuery } from '@tanstack/react-query'; @@ -34,9 +34,13 @@ export default function ProtectionOverview() { const t = useTranslations('Global'); const [openDropDownList, setOpenDropDownList] = useState(false); const dropDownList = useRef(null); - useClickOutside(dropDownList, () => { - setOpenDropDownList(false) - }); + useClickOutside( + dropDownList, + () => { + setOpenDropDownList(false) + }, + openDropDownList + ); const { data: filesInfo, diff --git a/src/app/ui/header/headerPanel.tsx b/src/app/ui/header/headerPanel.tsx index 2b7dc12..98172be 100644 --- a/src/app/ui/header/headerPanel.tsx +++ b/src/app/ui/header/headerPanel.tsx @@ -3,12 +3,14 @@ import UserMenuButton from './userMenuButton'; import Link from 'next/link'; import LanguageSwitcher from '@/app/components/LanguageSwitcher'; import { useTranslations } from 'next-intl'; +import BurgerMenu from '@/app/ui/navigation/burger-menu'; export default function HeaderPanel() { const t = useTranslations("Global"); return (
+
(null); const t = useTranslations('Global'); - useClickOutside(menuRef, () => { - setIsOpen(false); - }); + useClickOutside( + menuRef, + () => { + setIsOpen(false); + }, + isOpen + ); const handleButtonClick = () => { if (!isOpen) { @@ -54,7 +58,7 @@ export default function NotificationsButton() {
- +
diff --git a/src/app/ui/header/userMenuButton.tsx b/src/app/ui/header/userMenuButton.tsx index dfd2d84..f813a44 100644 --- a/src/app/ui/header/userMenuButton.tsx +++ b/src/app/ui/header/userMenuButton.tsx @@ -25,9 +25,13 @@ export default function UserMenuButton() { }) - useClickOutside(menuRef, () => { - setIsOpen(false); - }); + useClickOutside( + menuRef, + () => { + setIsOpen(false); + }, + isOpen + ); const handleButtonClick = () => { if (!isOpen) { diff --git a/src/app/ui/icons/icons.tsx b/src/app/ui/icons/icons.tsx index 12cd2c4..d6af85d 100644 --- a/src/app/ui/icons/icons.tsx +++ b/src/app/ui/icons/icons.tsx @@ -139,4 +139,10 @@ export function IconDelete() { return ( ) +} + +export function IconBurgerMenu() { + return ( + + ) } \ No newline at end of file diff --git a/src/app/ui/nav-links.tsx b/src/app/ui/nav-links.tsx deleted file mode 100644 index ec0e340..0000000 --- a/src/app/ui/nav-links.tsx +++ /dev/null @@ -1,113 +0,0 @@ -'use client'; - -import Link from 'next/link'; -import { usePathname } from 'next/navigation'; -import clsx from 'clsx'; -import Logo from '@/app/ui/logo'; -import DropDownList from '@/app/ui/nav-link-dropdown'; -import { logout } from '@/app/actions/auth'; -import { useTranslations } from 'next-intl'; - -export default function NavLinks() { - const pathname = usePathname().replace('/en/', '/').replace('/ru/', '/'); - const t = useTranslations('Global'); - - const links = [ - { - name: t('reports'), - href: '/pages/reports', - img: 'M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zM9 17H7v-7h2v7zm4 0h-2V7h2v10zm4 0h-2v-4h2v4z' - }, - { - name: t('settings'), - href: '/pages/settings', - img: 'M19.14,12.94c0.04-0.3,0.06-0.61,0.06-0.94c0-0.32-0.02-0.64-0.07-0.94l2.03-1.58c0.18-0.14,0.23-0.41,0.12-0.61 l-1.92-3.32c-0.12-0.22-0.37-0.29-0.59-0.22l-2.39,0.96c-0.5-0.38-1.03-0.7-1.62-0.94L14.4,2.81c-0.04-0.24-0.24-0.41-0.48-0.41 h-3.84c-0.24,0-0.43,0.17-0.47,0.41L9.25,5.35C8.66,5.59,8.12,5.92,7.63,6.29L5.24,5.33c-0.22-0.08-0.47,0-0.59,0.22L2.74,8.87 C2.62,9.08,2.66,9.34,2.86,9.48l2.03,1.58C4.84,11.36,4.82,11.69,4.82,12s0.02,0.64,0.07,0.94l-2.03,1.58 c-0.18,0.14-0.23,0.41-0.12,0.61l1.92,3.32c0.12,0.22,0.37,0.29,0.59,0.22l2.39-0.96c0.5,0.38,1.03,0.7,1.62,0.94l0.36,2.54 c0.05,0.24,0.24,0.41,0.48,0.41h3.84c0.24,0,0.44-0.17,0.47-0.41l0.36-2.54c0.59-0.24,1.13-0.56,1.62-0.94l2.39,0.96 c0.22,0.08,0.47,0,0.59-0.22l1.92-3.32c0.12-0.22,0.07-0.47-0.12-0.61L19.14,12.94z M12,15.6c-1.98,0-3.6-1.62-3.6-3.6 s1.62-3.6,3.6-3.6s3.6,1.62,3.6,3.6S13.98,15.6,12,15.6z' - }, - { - name: t('my-content'), - href: '/pages/my-content', - img: 'M20 6h-2.18c.11-.31.18-.65.18-1a2.996 2.996 0 0 0-5.5-1.65l-.5.67-.5-.68C10.96 2.54 10 2 9 2 7.34 2 6 3.34 6 5c0 .35.07.69.18 1H4c-1.11 0-1.99.89-1.99 2L2 19c0 1.11.89 2 2 2h16c1.11 0 2-.89 2-2V8c0-1.11-.89-2-2-2zm-5-2c.55 0 1 .45 1 1s-.45 1-1 1-1-.45-1-1 .45-1 1-1zM9 4c.55 0 1 .45 1 1s-.45 1-1 1-1-.45-1-1 .45-1 1-1z' - }, - { - name: t('referral-program'), - href: '/pages/refferals', - img: 'M16 4c0-1.11.89-2 2-2s2 .89 2 2-.89 2-2 2-2-.89-2-2zm4 18v-6h2.5l-2.54-7.63A1.5 1.5 0 0 0 18.54 8H16c-.8 0-1.54.37-2 1l-3 4v2h2l2.54-3.82L16.5 18H20z' - }, - { - name: t('violations'), - href: '/pages/violations', - img: 'M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z' - }, - { - name: t('search'), - href: '/pages/emptypage', - img: 'M15.5 14h-.79l-.28-.27C15.41 12.59 16 11.11 16 9.5 16 5.91 13.09 3 9.5 3S3 5.91 3 9.5 5.91 16 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z' - }, - { - name: 'API', - href: '/pages/emptypage', - img: 'M9.4 16.6L4.8 12l4.6-4.6L8 6l-6 6 6 6 1.4-1.4zm5.2 0L19.2 12l-4.6-4.6L16 6l6 6-6 6-1.4-1.4z' - } - ]; - - return ( -
- -
- ); -} diff --git a/src/app/ui/navigation/burger-menu.tsx b/src/app/ui/navigation/burger-menu.tsx new file mode 100644 index 0000000..6ba35bd --- /dev/null +++ b/src/app/ui/navigation/burger-menu.tsx @@ -0,0 +1,26 @@ +'use client' + +import { IconBurgerMenu } from '@/app/ui/icons/icons'; +import { useSideMenuStore } from '@/app/stores/sideMenuStore'; + +export default function BurgerMenu() { + const setMenuState = useSideMenuStore(s => s.setValue); + const menuState = useSideMenuStore(s => s.value); + + function openMenu() { + setMenuState(true); + } + + return ( + <> +
{ + openMenu(); + }} + > + +
+ + ) +} \ No newline at end of file diff --git a/src/app/ui/nav-link-dropdown.tsx b/src/app/ui/navigation/nav-link-dropdown.tsx similarity index 90% rename from src/app/ui/nav-link-dropdown.tsx rename to src/app/ui/navigation/nav-link-dropdown.tsx index deecffb..817db8a 100644 --- a/src/app/ui/nav-link-dropdown.tsx +++ b/src/app/ui/navigation/nav-link-dropdown.tsx @@ -3,11 +3,13 @@ import Link from 'next/link'; import clsx from 'clsx'; import { usePathname } from 'next/navigation'; import { useTranslations } from 'next-intl'; +import { useSideMenuStore } from '@/app/stores/sideMenuStore'; export default function DropDownList() { const pathname = usePathname().replace('/en/', '/').replace('/ru/', '/'); const [dropDownExpanded, setDropDownExpanded] = useState(false); const t = useTranslations('Global'); + const setMenuState = useSideMenuStore(s => s.setValue); function dropDownHandler() { setDropDownExpanded(!dropDownExpanded); @@ -58,6 +60,9 @@ export default function DropDownList() { 'bg-[#5659f1]': pathname === link.href, }, )} + onClick={() => { + setMenuState(false) + }} >

{link.name}

diff --git a/src/app/ui/navigation/nav-links.tsx b/src/app/ui/navigation/nav-links.tsx new file mode 100644 index 0000000..fc466b2 --- /dev/null +++ b/src/app/ui/navigation/nav-links.tsx @@ -0,0 +1,113 @@ +'use client'; + +import Link from 'next/link'; +import { usePathname } from 'next/navigation'; +import clsx from 'clsx'; +import Logo from '@/app/ui/logo'; +import DropDownList from '@/app/ui/navigation/nav-link-dropdown'; +import { logout } from '@/app/actions/auth'; +import { useTranslations } from 'next-intl'; +import navigation from './navigation.json'; +import { useSideMenuStore } from '@/app/stores/sideMenuStore'; +import { useRef } from 'react'; +import { useClickOutside } from '@/app/hooks/useClickOutside'; + +export default function NavLinks() { + const pathname = usePathname().replace('/en/', '/').replace('/ru/', '/'); + const t = useTranslations('Global'); + + const setMenuState = useSideMenuStore(s => s.setValue); + const menuState = useSideMenuStore(s => s.value); + const links = navigation; + + const sideMenuRef = useRef(null) + useClickOutside( + sideMenuRef, + () => { + setMenuState(false); + }, + menuState + ); + + return ( + + ); +} diff --git a/src/app/ui/navigation/navigation.json b/src/app/ui/navigation/navigation.json new file mode 100644 index 0000000..da6ad54 --- /dev/null +++ b/src/app/ui/navigation/navigation.json @@ -0,0 +1,37 @@ +[ + { + "name": "reports", + "href": "/pages/reports", + "img": "M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zM9 17H7v-7h2v7zm4 0h-2V7h2v10zm4 0h-2v-4h2v4z" + }, + { + "name": "settings", + "href": "/pages/settings", + "img": "M19.14,12.94c0.04-0.3,0.06-0.61,0.06-0.94c0-0.32-0.02-0.64-0.07-0.94l2.03-1.58c0.18-0.14,0.23-0.41,0.12-0.61 l-1.92-3.32c-0.12-0.22-0.37-0.29-0.59-0.22l-2.39,0.96c-0.5-0.38-1.03-0.7-1.62-0.94L14.4,2.81c-0.04-0.24-0.24-0.41-0.48-0.41 h-3.84c-0.24,0-0.43,0.17-0.47,0.41L9.25,5.35C8.66,5.59,8.12,5.92,7.63,6.29L5.24,5.33c-0.22-0.08-0.47,0-0.59,0.22L2.74,8.87 C2.62,9.08,2.66,9.34,2.86,9.48l2.03,1.58C4.84,11.36,4.82,11.69,4.82,12s0.02,0.64,0.07,0.94l-2.03,1.58 c-0.18,0.14-0.23,0.41-0.12,0.61l1.92,3.32c0.12,0.22,0.37,0.29,0.59,0.22l2.39-0.96c0.5,0.38,1.03,0.7,1.62,0.94l0.36,2.54 c0.05,0.24,0.24,0.41,0.48,0.41h3.84c0.24,0,0.44-0.17,0.47-0.41l0.36-2.54c0.59-0.24,1.13-0.56,1.62-0.94l2.39,0.96 c0.22,0.08,0.47,0,0.59-0.22l1.92-3.32c0.12-0.22,0.07-0.47-0.12-0.61L19.14,12.94z M12,15.6c-1.98,0-3.6-1.62-3.6-3.6 s1.62-3.6,3.6-3.6s3.6,1.62,3.6,3.6S13.98,15.6,12,15.6z" + }, + { + "name": "my-content", + "href": "/pages/my-content", + "img": "M20 6h-2.18c.11-.31.18-.65.18-1a2.996 2.996 0 0 0-5.5-1.65l-.5.67-.5-.68C10.96 2.54 10 2 9 2 7.34 2 6 3.34 6 5c0 .35.07.69.18 1H4c-1.11 0-1.99.89-1.99 2L2 19c0 1.11.89 2 2 2h16c1.11 0 2-.89 2-2V8c0-1.11-.89-2-2-2zm-5-2c.55 0 1 .45 1 1s-.45 1-1 1-1-.45-1-1 .45-1 1-1zM9 4c.55 0 1 .45 1 1s-.45 1-1 1-1-.45-1-1 .45-1 1-1z" + }, + { + "name": "referral-program", + "href": "/pages/refferals", + "img": "M16 4c0-1.11.89-2 2-2s2 .89 2 2-.89 2-2 2-2-.89-2-2zm4 18v-6h2.5l-2.54-7.63A1.5 1.5 0 0 0 18.54 8H16c-.8 0-1.54.37-2 1l-3 4v2h2l2.54-3.82L16.5 18H20z" + }, + { + "name": "violations", + "href": "/pages/violations", + "img": "M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 15l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z" + }, + { + "name": "search", + "href": "/pages/emptypage", + "img": "M15.5 14h-.79l-.28-.27C15.41 12.59 16 11.11 16 9.5 16 5.91 13.09 3 9.5 3S3 5.91 3 9.5 5.91 16 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z" + }, + { + "name": "API", + "href": "/pages/emptypage", + "img": "M9.4 16.6L4.8 12l4.6-4.6L8 6l-6 6 6 6 1.4-1.4zm5.2 0L19.2 12l-4.6-4.6L16 6l6 6-6 6-1.4-1.4z" + } +] \ No newline at end of file diff --git a/src/i18n/messages/en.json b/src/i18n/messages/en.json index fb206fa..9199f79 100644 --- a/src/i18n/messages/en.json +++ b/src/i18n/messages/en.json @@ -194,7 +194,8 @@ "total-violations": "Total violations", "new": "new", "in-progress": "In progress", - "it-decided": "It's decided" + "it-decided": "It's decided", + "API": "API" }, "Login-register-form": { "and": "and", diff --git a/src/i18n/messages/ru.json b/src/i18n/messages/ru.json index a561477..7ce8d55 100644 --- a/src/i18n/messages/ru.json +++ b/src/i18n/messages/ru.json @@ -194,7 +194,8 @@ "total-violations": "Всего нарушений", "new": "Новые", "in-progress": "В работе", - "it-decided": "Решено" + "it-decided": "Решено", + "API": "API" }, "Login-register-form": { "and": "и",