From 58ebd3bc0f00c532e97e9a5571471ffab87934ba Mon Sep 17 00:00:00 2001 From: AL-LCL Date: Fri, 19 May 2023 10:39:49 +0200 Subject: GOD-VIEW --- server/web/src/design/GlobalStyle.tsx | 52 +++++ server/web/src/design/components/Alert.design.tsx | 48 +++++ server/web/src/design/components/Card.design.tsx | 60 ++++++ server/web/src/design/components/Footer.design.tsx | 132 +++++++++++++ server/web/src/design/components/Select.design.tsx | 37 ++++ server/web/src/design/components/Server.design.tsx | 120 ++++++++++++ .../web/src/design/components/Sidebar.design.tsx | 108 +++++++++++ server/web/src/design/components/Window.design.tsx | 209 +++++++++++++++++++++ 8 files changed, 766 insertions(+) create mode 100644 server/web/src/design/GlobalStyle.tsx create mode 100644 server/web/src/design/components/Alert.design.tsx create mode 100644 server/web/src/design/components/Card.design.tsx create mode 100644 server/web/src/design/components/Footer.design.tsx create mode 100644 server/web/src/design/components/Select.design.tsx create mode 100644 server/web/src/design/components/Server.design.tsx create mode 100644 server/web/src/design/components/Sidebar.design.tsx create mode 100644 server/web/src/design/components/Window.design.tsx (limited to 'server/web/src/design') diff --git a/server/web/src/design/GlobalStyle.tsx b/server/web/src/design/GlobalStyle.tsx new file mode 100644 index 0000000..25c47bf --- /dev/null +++ b/server/web/src/design/GlobalStyle.tsx @@ -0,0 +1,52 @@ +import { createGlobalStyle } from 'styled-components'; + +// NOTE : rem unit is used instead of px. But +// the UI is still dependant on px units, mostly +// because of some javascript calculations +export const GlobalStyle = createGlobalStyle` + ::-webkit-scrollbar { + height: 0.2rem; + width: 0.4rem; + } + + ::-webkit-scrollbar-track { + background-color: rgb(5, 32, 58); + } + + ::-webkit-scrollbar-thumb { + background-color: rgb(31, 113, 145); + } + + ::placeholder { + text-transform: capitalize; + color: rgb(204, 204, 204); + opacity: 1; + } + + * { + box-sizing: border-box; + outline: none; + } + + body { + font-family: Arial, Helvetica, sans-serif; + background-color: rgb(5, 32, 58); + color: rgb(255, 255, 255); + font-size: 0.7rem; + font-weight: 100; + margin: 0; + } + + button, svg { + cursor: pointer; + } + + button { + transition: 150ms; + + :active { + transform: translateY(0.125rem); + transition: 150ms; + } + } +`; diff --git a/server/web/src/design/components/Alert.design.tsx b/server/web/src/design/components/Alert.design.tsx new file mode 100644 index 0000000..ff634bf --- /dev/null +++ b/server/web/src/design/components/Alert.design.tsx @@ -0,0 +1,48 @@ +import { IAlertButton } from '../../interfaces/design/AlertDesign.interface'; +import styled from 'styled-components'; + +const calcBgColor = (color: string) => { + switch (color) { + case 'SUCCESS': + return 'rgb(24, 79, 59)'; + case 'DANGER': + return 'rgb(175, 45, 45)'; + case 'WARNING': + return 'rgb(175, 121, 21)'; + case 'INFO': + return 'rgb(23, 52, 102)'; + } +}; + +export const AlertButton = styled('div') ` + background-color: ${(props) => calcBgColor(props.bgColor)}; + border: solid thin rgb(255, 255, 255); + grid-template-columns: 1fr auto; + color: rgb(255, 255, 255); + align-items: center; + min-height: 2.5rem; + text-align: center; + font-size: 0.8rem; + width: 17.5rem; + display: grid; + + @media (min-width: 768px) { + width: 22.5rem; + } +`; + +export const AlertButtonCross = styled('span')` + border-left: solid thin rgb(255, 255, 255); + -webkit-touch-callout: none; + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + padding: 0.5rem 1rem; + align-items: center; + font-size: 1.25rem; + user-select: none; + cursor: pointer; + display: grid; + height: 100%; +`; diff --git a/server/web/src/design/components/Card.design.tsx b/server/web/src/design/components/Card.design.tsx new file mode 100644 index 0000000..2eb67a3 --- /dev/null +++ b/server/web/src/design/components/Card.design.tsx @@ -0,0 +1,60 @@ +import styled from 'styled-components'; + +export const CardContainer = styled('div')` + border: solid thin rgb(31, 113, 145); + background-color: rgb(5, 32, 58); + // CONSTANT : left & right borders + left & right margin + width: calc(100% - 1.125rem); + color: rgb(255, 255, 255); + border-radius: 0.5rem; + display: inline-block; + margin: 0.5rem; + + @media (min-width: 992px) { + width: 46.5%; + } +`; + +export const CardHeader = styled('div')` + border-bottom: solid thin rgb(31, 113, 145); + padding: 0.5rem 0.5rem 0.625rem 0.5rem; + border-top-right-radius: 0.5rem; + border-top-left-radius: 0.5rem; + text-overflow: ellipsis; + white-space: nowrap; + font-size: 0.9rem; + text-align: left; + overflow: hidden; +`; + +export const CardFooter = styled('div')` + border-top: solid thin rgb(31, 113, 145); + border-bottom-right-radius: 0.5rem; + border-bottom-left-radius: 0.5rem; + grid-template-columns: 1fr 1fr; + display: grid; +`; + +export const CardFooterItem = styled('div')` + border-right: solid thin rgb(31, 113, 145); + justify-content: center; + align-items: center; + font-size: 0.65rem; + padding: 0.5rem 0; + cursor: pointer; + display: grid; + + :hover { + background-color: rgb(0, 55, 117); + transition: 250ms; + } + + :first-child { + border-bottom-left-radius: 0.5rem; + } + + :last-child { + border-bottom-right-radius: 0.5rem; + border-right: none; + } +`; diff --git a/server/web/src/design/components/Footer.design.tsx b/server/web/src/design/components/Footer.design.tsx new file mode 100644 index 0000000..a5cf586 --- /dev/null +++ b/server/web/src/design/components/Footer.design.tsx @@ -0,0 +1,132 @@ +import { IFooterDropdownContent } from '../../interfaces/design/FooterDesign.interface'; +import styled from 'styled-components'; + +export const FooterDropdown = styled('div')` + border-top: solid thin rgb(31, 93, 117); + background-color: rgb(5, 32, 58); + width: calc(100% - 1.2rem); + text-align: center; + position: fixed; + bottom: 4.45rem; + left: 0; +`; + +export const FooterDropdownToggle = styled('div')` + background-color: rgb(5, 32, 58); + color: rgb(0, 255, 255); + padding: 0.25rem 0; + cursor: pointer; +`; + +export const FooterWindowManager = styled('div')` + border-top: solid thin rgb(31, 93, 117); + background-color: rgb(5, 32, 58); + width: calc(100% - 1.2rem); + color: rgb(255, 255, 255); + -ms-overflow-style: none; + scrollbar-width: none; + white-space: nowrap; + text-align: center; + overflow-x: scroll; + overflow-y: hidden; + position: fixed; + height: 3.25rem; + bottom: 1.2rem; + left: 0; +`; + +export const FooterWindowButton = styled('button')` + border: solid thin rgb(31, 93, 117); + background-color: rgb(5, 32, 58); + margin: 0.578125rem 0.15rem; + color: rgb(255, 255, 255); + padding: 0.5rem 1.5rem; + border-radius: 5rem; + transition: 250ms; +`; + +export const FooterWindowClear = styled('button')` + border: solid thin rgb(225, 53, 57); + background-color: rgb(5, 32, 58); + margin: 0.578125rem 0.15rem; + color: rgb(255, 255, 255); + padding: 0.5rem 1.5rem; + border-radius: 5rem; + transition: 250ms; +`; + +export const FooterBlock = styled('div')` + background-color: rgb(5, 32, 58); + color: rgb(255, 255, 255); + margin: 1.1875rem 0; +`; + +export const FooterDropdownContent = styled('div') ` + background-color: rgb(5, 32, 58); + overflow-y: scroll; + transition: 250ms; + padding: 0; + height: 0; + + ${({ active }: any) => + active && + ` + border-top: solid thin rgb(31, 93, 117); + padding: 0.5rem 0; + transition: 250ms; + height: 9.2rem; + + @media (min-width: 1280px) { + height: 7.2rem; + } + + @media (min-width: 2000px) { + height: 5.2rem; + } + `} +`; + +export const FooterNameSpaceButton = styled('button')` + border: solid thin rgb(225, 53, 57); + background-color: rgb(225, 53, 57); + color: rgb(255, 255, 255); + padding: 0.4rem 1rem; + border-radius: 5rem; + transition: none; + cursor: text; + + :active { + transform: none; + transition: none; + } +`; + +export const FooterDropdownButton = styled('button')` + background-color: rgb(31, 93, 117); + color: rgb(255, 255, 255); + border: rgb(31, 93, 117); + padding: 0.4rem 1rem; + border-radius: 5rem; + margin: 0.15rem; +`; + +export const FooterMenu = styled('div')` + border-top: solid thin rgb(31, 93, 117); + background-color: rgb(5, 32, 58); + width: calc(100% - 1.2rem); + color: rgb(255, 255, 255); + position: fixed; + height: 1.2rem; + bottom: 0; + left: 0; +`; + +export const FooterParagraph = styled('p')` + text-overflow: ellipsis; + padding-top: 0.15rem; + white-space: nowrap; + font-size: 0.75rem; + overflow: hidden; + height: 1.2rem; + margin-top: 0; +`; diff --git a/server/web/src/design/components/Select.design.tsx b/server/web/src/design/components/Select.design.tsx new file mode 100644 index 0000000..92e6719 --- /dev/null +++ b/server/web/src/design/components/Select.design.tsx @@ -0,0 +1,37 @@ +import styled from 'styled-components'; + +export const SelectContainer = styled('div')` + position: fixed; +`; + +export const SelectRow = styled('div')` + border-bottom: solid thin rgb(31, 113, 145); + border-right: solid thin rgb(31, 113, 145); + border-left: solid thin rgb(31, 113, 145); + background-color: rgb(5, 32, 58); + font-size: 0.8rem; + transition: 250ms; + padding: 0.4rem; + cursor: pointer; + width: 8.5rem; + + :hover { + background-color: rgb(0, 55, 117); + transition: 250ms; + } + + :first-child { + border-top: solid thin rgb(31, 113, 145); + border-top-right-radius: 0.25rem; + border-top-left-radius: 0.25rem; + } + + :last-child { + border-bottom-right-radius: 0.25rem; + border-bottom-left-radius: 0.25rem; + } + + > svg { + vertical-align: text-bottom; + } +`; diff --git a/server/web/src/design/components/Server.design.tsx b/server/web/src/design/components/Server.design.tsx new file mode 100644 index 0000000..b6296b6 --- /dev/null +++ b/server/web/src/design/components/Server.design.tsx @@ -0,0 +1,120 @@ +import styled, { css } from 'styled-components'; +import { + IServerTableRow, + IServerTableBar +} from '../../interfaces/design/ServerDesign.interface'; + +const tableColumn = css` + border: solid thin rgb(31, 113, 145); + text-overflow: ellipsis; + white-space: nowrap; + max-width: 3.1rem; + border-top: none; + overflow: hidden; + padding: 0.3rem; +`; + +const tableResponsive = css` + @media (max-width: 767px) { + display: block; + } +`; + +export const ServerTable = styled('table')` + width: calc(100% - 1.125rem); + color: rgb(255, 255, 255); + border-collapse: collapse; + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + margin-bottom: 5.9rem; + -ms-user-select: none; + text-align: center; + user-select: none; + ${tableResponsive} +`; + +export const ServerTableHead = styled('thead')` + background-color: rgb(31, 93, 117); + + @media (max-width: 767px) { + display: none; + } +`; + +export const ServerTableBody = styled('tbody')` + background-color: rgb(5, 32, 58); + ${tableResponsive} + + > tr:first-child { + padding-top: 1.5rem; + } + + > tr:last-child { + padding-bottom: 1.5rem; + } +`; + +export const ServerTableRow = styled('tr') ` + ${(props) => props.activeSession && `color: ${props.activeSession};`} + padding: 0.75rem 1.5rem; + ${tableResponsive} + + > td:first-child { + border-top: solid thin rgb(31, 113, 145); + } +`; + +export const ServerTableHeader = styled('th')` + ${tableColumn} +`; + +export const ServerTableData = styled('td')` + ${tableColumn} + + @media (max-width: 767px) { + min-height: 1.4125rem; + padding-right: 1rem; + position: relative; + text-align: right; + padding-left: 45%; + overflow: hidden; + max-width: 100%; + display: block; + + &:before { + content: attr(data-label); + position: absolute; + padding-left: 1rem; + text-align: left; + width: 55%; + left: 0; + } + } +`; + +export const ServerTableImage = styled('img')` + vertical-align: text-bottom; + margin-right: 0.15rem; + height: 0.90625rem; + width: 0.90625rem; +`; + +export const ServerTableBarBg = styled('div')` + background-color: rgb(31, 93, 117); +`; + +export const ServerTableBar = styled('div') ` + ${(props) => props.width && `width: ${props.width}%;`} + background-color: rgb(24, 79, 59); + margin: 0.0625rem 0; + height: 0.375rem; +`; + +export const ServerBlock = styled('div')` + background-color: rgb(31, 93, 117); + width: calc(100% - 1.2rem); + color: rgb(255, 255, 255); + text-align: center; + padding: 0.8rem 0; +`; diff --git a/server/web/src/design/components/Sidebar.design.tsx b/server/web/src/design/components/Sidebar.design.tsx new file mode 100644 index 0000000..4496e79 --- /dev/null +++ b/server/web/src/design/components/Sidebar.design.tsx @@ -0,0 +1,108 @@ +import { ISidebarSlide } from '../../interfaces/design/SidebarDesign.interface'; +import styled from 'styled-components'; + +export const SidebarDropdown = styled('div')` + background-color: rgb(5, 32, 58); + grid-template-columns: 1fr auto; + color: rgb(0, 255, 255); + position: fixed; + display: grid; + height: 100%; + z-index: 999; + right: 0; + top: 0; +`; + +export const SidebarDropdownButton = styled('div')` + border-left: solid thin rgb(31, 113, 145); + padding: 0 0.25rem 0 0.2rem; + color: rgb(0, 255, 255); + align-items: center; + cursor: pointer; + width: 1.2rem; + display: grid; + height: 100vh; + z-index: 999; +`; + +export const SidebarDropdownContent = styled('div') ` + overflow-x: hidden; + text-align: center; + transition: 250ms; + overflow-y: auto; + opacity: 0; + padding: 0; + width: 0; + + ${({ active }: any) => + active && + ` + border-left: solid thin rgb(31, 113, 145); + width: calc(100vw - 1.2rem); + opacity: 1; + + @media (min-width: 576px) { + width: 65vw; + } + `} +`; + +export const SidebarStreamContent = styled('div')` + @media (min-width: 992px) { + padding: 0.5rem 0; + } + + @media (min-width: 1200px) { + padding: 1rem 0; + } + + @media (min-width: 1600px) { + padding: 1.5rem 0; + } +`; + +export const SidebarStream = styled('div')` + border-bottom: solid thin rgb(31, 113, 145); + border-top: solid thin rgb(31, 113, 145); + background-color: rgb(5, 32, 58); + color: rgb(255, 255, 255); + text-align: center; + padding: 0.8rem 0; +`; + +export const SidebarStreamSection = styled('div')` + grid-template-columns: 1fr auto; + display: grid; +`; + +export const SidebarStreamInput = styled('input')` + padding: 0.45rem 0.45rem 0.45rem 0.6rem; + border: solid thin rgb(31, 93, 117); + background-color: rgb(5, 32, 58); + width: calc(100% - 0.8rem); + color: rgb(255, 255, 255); + border-radius: 5rem; + font-size: 0.8rem; + margin: 0.4rem; +`; + +export const SidebarStreamButton = styled('button')` + border: solid thin rgb(31, 93, 117); + background-color: rgb(5, 32, 58); + margin: 0.4rem 0.4rem 0.4rem 0; + color: rgb(255, 255, 255); + padding: 0.5rem 2rem; + border-radius: 5rem; + transition: 250ms; + + @media (min-width: 576px) { + padding: 0.5rem 4rem; + } +`; + +export const SidebarBlock = styled('div')` + background-color: rgb(31, 93, 117); + color: rgb(255, 255, 255); + text-align: center; + padding: 0.8rem 0; +`; diff --git a/server/web/src/design/components/Window.design.tsx b/server/web/src/design/components/Window.design.tsx new file mode 100644 index 0000000..1daac95 --- /dev/null +++ b/server/web/src/design/components/Window.design.tsx @@ -0,0 +1,209 @@ +import styled from 'styled-components'; + +export const WindowData = styled('div')` + border: solid 0.0625rem rgb(178, 178, 178); + background-color: rgb(5, 32, 58); + color: rgb(255, 255, 255); + min-height: 2.1875rem; + min-width: 18rem; + overflow: hidden; + position: fixed; + resize: both; + height: 55vh; + width: 40vw; + + &:after { + cursor: nwse-resize; + position: absolute; + display: block; + height: 1rem; + width: 1rem; + content: ''; + bottom: 0; + right: 0; + } +`; + +export const WindowTopBar = styled('div')` + border-bottom: solid 0.0625rem rgb(31, 93, 117); + background-color: rgb(225, 53, 57); + grid-template-columns: 1fr auto; + align-items: center; + text-align: right; + display: grid; +`; + +export const WindowTopBarTitle = styled('div')` + text-overflow: ellipsis; + text-align: left; + overflow: hidden; + padding: 0.5rem; + cursor: grab; +`; + +export const WindowTopBarAction = styled('div')` + padding: 0.5rem; +`; + +export const WindowInputGroup = styled('div')` + padding: 0 0.75rem 1rem 0.75rem; + grid-template-columns: auto 1fr; + justify-content: center; + align-items: center; + text-align: center; + grid-gap: 0.5rem; + display: grid; + + :first-child { + padding-top: 0.75rem; + } +`; + +export const WindowContent = styled('div')` + height: calc(100% - 2.1875rem); + overflow-x: auto; +`; + +export const WindowForm = styled('form')` + border-bottom: solid 0.0625rem rgb(31, 93, 117); + border-right: solid 0.0625rem rgb(31, 93, 117); + border-left: solid 0.0625rem rgb(31, 93, 117); + margin: 0 0.75rem 0.75rem 0.75rem; + width: calc(100% - 1.5rem); + text-align: left; +`; + +export const WindowLabel = styled('label')` + text-transform: capitalize; + font-size: 0.8rem; +`; + +export const WindowInput = styled('input')` + border: solid 0.0625rem rgb(31, 93, 117); + padding: 0.45rem 0.45rem 0.45rem 0.6rem; + background-color: rgb(5, 32, 58); + color: rgb(255, 255, 255); + border-radius: 5rem; + font-size: 0.8rem; +`; + +export const WindowCheckbox = styled('div')` + border: solid 0.0625rem rgb(31, 93, 117); + background-color: rgb(5, 32, 58); + border-radius: 3.125rem; + position: relative; + width: 4.6875rem; + height: 1.5rem; + z-index: 0; + + &:before { + color: rgb(255, 255, 255); + position: absolute; + font-weight: bold; + right: 0.625rem; + content: 'OFF'; + top: 0.25rem; + } + + &:after { + color: rgb(255, 255, 255); + position: absolute; + font-weight: bold; + left: 0.625rem; + content: 'ON'; + top: 0.25rem; + z-index: 0; + } + + label { + box-shadow: 0 0.125rem 0.5rem rgb(31, 93, 117); + background-color: rgb(255, 255, 255); + border-radius: 3.125rem; + position: absolute; + transition: 250ms; + cursor: pointer; + width: 1.875rem; + display: block; + top: 0.1875rem; + left: 0.25rem; + height: 1rem; + z-index: 1; + } + + input[type="checkbox"] { + visibility: hidden; + + &:checked + label { + left: 2.4375rem; + } + } +`; + +export const WindowFormSubmit = styled('div')` + padding: 0.25rem 0.75rem 0.75rem 0.75rem; +`; + +export const WindowFormButton = styled('button')` + border: solid 0.0625rem rgb(31, 93, 117); + background-color: rgb(5, 32, 58); + color: rgb(255, 255, 255); + padding: 0.5rem 0.25rem; + border-radius: 5rem; + width: 10rem; +`; + +export const WindowFormClear = styled('button')` + border: solid 0.0625rem rgb(31, 93, 117); + padding: 0.45rem 0.4rem 0.55rem 0.4rem; + background-color: rgb(5, 32, 58); + color: rgb(255, 255, 255); + margin-left: 0.5rem; + border-radius: 5rem; + width: 2rem; + + > svg { + vertical-align: bottom; + } +`; + +export const WindowResult = styled('div')` + font-family: 'Courier New', Courier, monospace; + border: solid 0.0625rem rgb(31, 93, 117); + padding: 0.75rem 0.75rem 0 0.75rem; + margin: 0.75rem 0.75rem 0 0.75rem; + line-height: 1.2rem; + min-height: 7.5rem; + font-size: 0.8rem; + text-align: left; + white-space: pre; + overflow: auto; + + ::-webkit-scrollbar { + height: 0.3rem; + width: 0.3rem; + } + + > div { + border: solid 0.0625rem rgb(31, 113, 145); + background-color: rgb(5, 32, 58); + margin-bottom: 0.75rem; + padding: 0.25rem; + display: table; + width: 100%; + } + + table { + border-collapse: collapse; + } + + td, + th { + border: solid 0.0625rem rgb(31, 113, 145); + background-color: rgb(5, 32, 58); + padding: 0.25rem 0.5rem; + } + + th { + background-color: rgb(31, 93, 117); + } +`; -- cgit v1.2.3