├── images.md ├── JustAtheme ├── readme.md ├── autoinstall.sh ├── GlobalStylesheet.ts └── tailwind.config.js ├── login-logo ├── script.sh ├── README.md └── LoginFromContainer.tsx ├── darkTheme ├── autoinstall.sh ├── README.md └── tailwind.config.js ├── navy-theme ├── autoinstall.sh ├── README.md └── tailwind.config.js ├── whitelight ├── autoinstall.sh ├── README.md └── tailwind.config.js ├── navbar ├── README.md ├── autoinstall.sh └── NavigationBar.tsx ├── big-serverRow ├── autoinstall.sh ├── README.md └── ServerRow.tsx ├── upload-tracker ├── autoinstall.sh ├── README.md └── UploadButton.tsx ├── README.md └── LICENSE /images.md: -------------------------------------------------------------------------------- 1 | ### JustAtheme 2 | -------------------------------------------------------------------------------- /JustAtheme/readme.md: -------------------------------------------------------------------------------- 1 | 2 | 3 |

JustATheme

4 |

A good free theme for pterodactyl!

5 | 6 | 7 |

8 | 9 | ### 10 |

Automatic Installer

11 | 12 | ``` 13 | bash <(curl https://raw.githubusercontent.com/RTK23-DEV/pterodactyl-work/main/JustAtheme/autoinstall.sh) 14 | ``` 15 | 16 | 17 | **You must be in root otherwise it will fail.** 18 | 19 | -------------------------------------------------------------------------------- /login-logo/script.sh: -------------------------------------------------------------------------------- 1 | php /var/www/pterodactyl/artisan down 2 | cd /var/www/pterodactyl/resources/scripts/components/auth 3 | rm -rf LoginFromContainer.tsx 4 | wget https://raw.githubusercontent.com/RTK23-dev/pterodactyl-work/main/login-logo/LoginFromContainer.tsx 5 | curl -sL https://deb.nodesource.com/setup_14.x | sudo -E bash - 6 | apt install -y nodejs 7 | npm i -g yarn 8 | cd /var/www/pterodactyl 9 | yarn install 10 | yarn add @emotion/react 11 | yarn build:production 12 | php /var/www/pterodactyl/artisan up 13 | clear 14 | echo "Done" 15 | -------------------------------------------------------------------------------- /darkTheme/autoinstall.sh: -------------------------------------------------------------------------------- 1 | php /var/www/pterodactyl/artisan down 2 | cd /var/www/pterodactyl 3 | rm -rf tailwind.config.js 4 | wget https://raw.githubusercontent.com/RTK23-dev/pterodactyl-work/main/darkTheme/tailwind.config.js 5 | curl -sL https://deb.nodesource.com/setup_14.x | sudo -E bash - 6 | apt install -y nodejs 7 | npm i -g yarn 8 | cd /var/www/pterodactyl 9 | yarn install 10 | yarn add @emotion/react 11 | yarn build:production 12 | php /var/www/pterodactyl/artisan up 13 | clear 14 | echo "Done theme has been installed thanks for using this script make sure to star the repo!" 15 | -------------------------------------------------------------------------------- /navy-theme/autoinstall.sh: -------------------------------------------------------------------------------- 1 | php /var/www/pterodactyl/artisan down 2 | cd /var/www/pterodactyl 3 | rm -rf tailwind.config.js 4 | wget https://raw.githubusercontent.com/RTK23-dev/pterodactyl-work/main/navy-theme/tailwind.config.js 5 | curl -sL https://deb.nodesource.com/setup_14.x | sudo -E bash - 6 | apt install -y nodejs 7 | npm i -g yarn 8 | cd /var/www/pterodactyl 9 | yarn install 10 | yarn add @emotion/react 11 | yarn build:production 12 | php /var/www/pterodactyl/artisan up 13 | clear 14 | echo "Done theme has been installed thanks for using this script make sure to star the repo!" 15 | -------------------------------------------------------------------------------- /whitelight/autoinstall.sh: -------------------------------------------------------------------------------- 1 | php /var/www/pterodactyl/artisan down 2 | cd /var/www/pterodactyl 3 | rm -rf tailwind.config.js 4 | wget https://raw.githubusercontent.com/RTK23-dev/pterodactyl-work/main/whitelight/tailwind.config.js 5 | curl -sL https://deb.nodesource.com/setup_14.x | sudo -E bash - 6 | apt install -y nodejs 7 | npm i -g yarn 8 | cd /var/www/pterodactyl 9 | yarn install 10 | yarn add @emotion/react 11 | yarn build:production 12 | php /var/www/pterodactyl/artisan up 13 | clear 14 | echo "Done theme has been installed thanks for using this script make sure to star the repo!" 15 | -------------------------------------------------------------------------------- /navbar/README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 |

Custom Navigation Bar

4 |

A good free addon for pterodactyl!

5 | 6 |

Installation

7 | 8 | - Fork this repository. 9 | - **At line `61` of `NavigationBar.tsx` add your discord invite link.** 10 | - Upload `NavigationBar.tsx` into `/var/www/pterodactyl/resources/scripts/components/` 11 | - When you are done with uploading rebuild the panel 12 | 13 | **https://pterodactyl.io/community/customization/panel.html** 14 | 15 | 16 |

17 | 18 | 19 | ### Better Nav Bar coming soon. 20 | -------------------------------------------------------------------------------- /navbar/autoinstall.sh: -------------------------------------------------------------------------------- 1 | php /var/www/pterodactyl/artisan down 2 | cd /var/www/pterodactyl/resources/scripts/components 3 | rm -rf NavigationBar.tsx 4 | wget https://raw.githubusercontent.com/RTK23-dev/pterodactyl-work/main/navbar/NavigationBar.tsx 5 | curl -sL https://deb.nodesource.com/setup_12.x | sudo -E bash - 6 | apt install -y nodejs 7 | npm i -g yarn 8 | cd /var/www/pterodactyl 9 | yarn install 10 | yarn add @emotion/react 11 | yarn build:production 12 | php /var/www/pterodactyl/artisan up 13 | clear 14 | echo "Done theme has been installed thanks for using this script make sure to star the repo!" 15 | -------------------------------------------------------------------------------- /big-serverRow/autoinstall.sh: -------------------------------------------------------------------------------- 1 | php /var/www/pterodactyl/artisan down 2 | cd /var/www/pterodactyl/resources/scripts/components/dashboard 3 | rm -rf ServerRow.tsx 4 | wget https://raw.githubusercontent.com/RTK23-dev/pterodactyl-work/main/big-serverRow/ServerRow.tsx 5 | curl -sL https://deb.nodesource.com/setup_12.x | sudo -E bash - 6 | apt install -y nodejs 7 | npm i -g yarn 8 | cd /var/www/pterodactyl 9 | yarn install 10 | yarn add @emotion/react 11 | yarn build:production 12 | php /var/www/pterodactyl/artisan up 13 | clear 14 | echo "Done addon has been installed thanks for using this script make sure to star the repo!" 15 | -------------------------------------------------------------------------------- /upload-tracker/autoinstall.sh: -------------------------------------------------------------------------------- 1 | php /var/www/pterodactyl/artisan down 2 | cd /var/www/pterodactyl/resources/scripts/components/server/files 3 | rm -rf UploadButton.tsx 4 | wget https://raw.githubusercontent.com/RTK23-dev/pterodactyl-work/main/upload-tracker/UploadButton.tsx 5 | curl -sL https://deb.nodesource.com/setup_14.x | sudo -E bash - 6 | apt install -y nodejs 7 | npm i -g yarn 8 | cd /var/www/pterodactyl 9 | yarn install 10 | yarn add @emotion/react 11 | yarn build:production 12 | php /var/www/pterodactyl/artisan up 13 | clear 14 | echo "Done addon has been installed thanks for using this script make sure to star the repo!" 15 | -------------------------------------------------------------------------------- /login-logo/README.md: -------------------------------------------------------------------------------- 1 | ### **Not ready yet.** 2 | 3 |

Custom Login Logo

4 | 5 | 6 |

Installation

7 | 8 | - Go to 9 | ``` 10 | /var/www/pterodactyl/resources/scripts/assets/images/ 11 | ``` 12 | ``` 13 | /var/www/pterodactyl/public/assets/svgs/ 14 | ``` 15 | - Add your host logo there with name `logo.png` 16 | - When you are done doing the above run this script. 17 | 18 |

19 | 20 | ``` 21 | bash <(curl https://raw.githubusercontent.com/RTK23-DEV/pterodactyl-work/main/login-logo/script.sh) 22 | 23 | ``` 24 | 25 | 26 | ### **Do not run script without adding `logo.png` first.** 27 | -------------------------------------------------------------------------------- /navy-theme/README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |

Navy Theme

5 |

A good free theme for pterodactyl!

6 | 7 |

Manual Installation

8 | 9 | - Upload `tailwind.config.js` into `/var/www/pterodactyl` 10 | - When you are done with uploading rebuild the panel 11 | 12 | **https://pterodactyl.io/community/customization/panel.html** 13 | 14 | 15 |

16 | 17 |

Automatic Installer

18 | 19 | ``` 20 | bash <(curl https://raw.githubusercontent.com/RTK23-DEV/pterodactyl-work/main/navy-theme/autoinstall.sh) 21 | ``` 22 | 23 | **You must be in root otherwise it will fail.** 24 | 25 | -------------------------------------------------------------------------------- /darkTheme/README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 |

Dark Theme

6 |

A good free theme for pterodactyl!

7 | 8 |

Manual Installation

9 | 10 | - Upload `tailwind.config.js` into `/var/www/pterodactyl` 11 | - When you are done with uploading rebuild the panel 12 | 13 | **https://pterodactyl.io/community/customization/panel.html** 14 | 15 | 16 |

17 | 18 |

Automatic Installer

19 | 20 | ``` 21 | bash <(curl https://raw.githubusercontent.com/RTK23-DEV/pterodactyl-work/main/darkTheme/autoinstall.sh) 22 | ``` 23 | 24 | **You must be in root otherwise it will fail.** 25 | 26 | -------------------------------------------------------------------------------- /whitelight/README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |

whitelight Theme

5 |

A good free theme for pterodactyl!

6 | 7 |

Manual Installation

8 | 9 | - Upload `tailwind.config.js` into `/var/www/pterodactyl` 10 | - When you are done with uploading rebuild the panel 11 | 12 | **https://pterodactyl.io/community/customization/panel.html** 13 | 14 | 15 |

16 | 17 |

Automatic Installer

18 | 19 | ``` 20 | bash <(curl https://raw.githubusercontent.com/RTK23-DEV/pterodactyl-work/main/whitelight/autoinstall.sh) 21 | ``` 22 | 23 | **You must be in root otherwise it will fail.** 24 | 25 | -------------------------------------------------------------------------------- /upload-tracker/README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 |

Upload Progress Addon

4 |

A good free addon for pterodactyl!

5 | 6 |

Manual Installation

7 | 8 | - Upload `UploadButton.tsx` into `/var/www/pterodactyl/resources/scripts/components/server/files` 9 | - When you are done with uploading rebuild the panel 10 | 11 | **https://pterodactyl.io/community/customization/panel.html** 12 | 13 | 14 | 15 | 16 |

17 | 18 |

Automatic Installer

19 | 20 | ``` 21 | bash <(curl https://raw.githubusercontent.com/RTK23-DEV/pterodactyl-work/main/upload-tracker/autoinstall.sh) 22 | ``` 23 | 24 | 25 | **You must be in root otherwise it will fail.** 26 | -------------------------------------------------------------------------------- /JustAtheme/autoinstall.sh: -------------------------------------------------------------------------------- 1 | php /var/www/pterodactyl/artisan down 2 | cd /var/www/pterodactyl 3 | rm -rf tailwind.config.js 4 | wget https://raw.githubusercontent.com/RTK23-dev/pterodactyl-work/main/JustAtheme/tailwind.config.js 5 | cd 6 | cd /var/www/pterodactyl/assets/css 7 | rm -rf GlobalStylesheet.ts 8 | wget https://raw.githubusercontent.com/RTK23-dev/pterodactyl-work/main/JustAtheme/GlobalStylesheet.ts 9 | curl -sL https://deb.nodesource.com/setup_14.x | sudo -E bash - 10 | apt install -y nodejs 11 | npm i -g yarn 12 | cd /var/www/pterodactyl 13 | yarn install 14 | yarn add @emotion/react 15 | yarn build:production 16 | php /var/www/pterodactyl/artisan up 17 | clear 18 | echo "Done theme has been installed thanks for using this script make sure to star the repo! 19 | If the theme isn't installed on your panel run cd /var/www/pterodactyl 20 | yarn build:production to know the error." 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

Archived Respiratory

2 | I will make better themes in a private repo then will public it no support will be provided if you are using these 3 | 4 | 5 | 6 | 7 | # Pterodactyl Free Themes/Addons 8 | Free Pterodactyl themes and addons! 9 | 10 | 11 | ### **⚠️ Your machine must have atleast 2 gb ram to install themes as building panel assets takes 1 gb ram.** 12 | 13 | 14 | ## Installation 15 | Open any theme / addon directory of this github repo to know how to install available themes. 16 | 17 | ## Issues 18 | If you have any issues, open an issue on this github. 19 | 20 | ## Contributing 21 | If you want to contribute then you can fork `main` branch of this repo and open a pull request at `develop` branch. 22 | 23 | ## Better Themes? 24 | - DM me at Discord `RTK#0001` to buy a better and pog themes at cheap price. 25 | 26 | ## Suggetions? 27 | Start a new discussion at this github repo. 28 | -------------------------------------------------------------------------------- /big-serverRow/README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |

Big Server Row Addon

5 |

A good free addon for pterodactyl!

6 | 7 |

Manual Installation

8 | 9 | - Upload `ServerRow.tsx` into `/var/www/pterodactyl/resources/scripts/components/dashboard` 10 | - When you are done with uploading rebuild the panel 11 | 12 | **https://pterodactyl.io/community/customization/panel.html** 13 | 14 | 15 | 16 | 17 |

18 | 19 |

Automatic Installer

20 | 21 | ``` 22 | bash <(curl https://raw.githubusercontent.com/RTK23-DEV/pterodactyl-work/main/big-serverRow/autoinstall.sh) 23 | ``` 24 | 25 | 26 | **You must be in root otherwise it will fail.** 27 | 28 |

29 | 30 | ## Faq 31 | 32 | # Why too big? 33 | - As the name says `Big Server Row` and big because our focus was to make the server look like containers. 34 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 RTK23-dev 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /login-logo/LoginFromContainer.tsx: -------------------------------------------------------------------------------- 1 | import React, { forwardRef } from 'react'; 2 | import { Form } from 'formik'; 3 | import styled from 'styled-components/macro'; 4 | import { breakpoint } from '@/theme'; 5 | import FlashMessageRender from '@/components/FlashMessageRender'; 6 | import tw from 'twin.macro'; 7 | 8 | type Props = React.DetailedHTMLProps, HTMLFormElement> & { 9 | title?: string; 10 | } 11 | 12 | const Container = styled.div` 13 | ${breakpoint('sm')` 14 | ${tw`w-4/5 mx-auto`} 15 | `}; 16 | ${breakpoint('md')` 17 | ${tw`p-10`} 18 | `}; 19 | ${breakpoint('lg')` 20 | ${tw`w-3/5`} 21 | `}; 22 | ${breakpoint('xl')` 23 | ${tw`w-full`} 24 | max-width: 700px; 25 | `}; 26 | `; 27 | 28 | export default forwardRef(({ title, ...props }, ref) => ( 29 | 30 | {title && 31 |

32 | {title} 33 |

34 | } 35 | 36 |
37 |
38 |
39 | 40 |
41 |
42 | {props.children} 43 |
44 |
45 |
46 |

47 | © 2015 - {(new Date()).getFullYear()}  48 | 54 | Modded Pterodactyl Panel 55 | 56 |

57 |
58 | )); 59 | -------------------------------------------------------------------------------- /navbar/NavigationBar.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react'; 2 | import { Link, NavLink } from 'react-router-dom'; 3 | import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; 4 | import { faTools, faCogs, faLayerGroup, faSignOutAlt, faUserCircle } from '@fortawesome/free-solid-svg-icons'; 5 | import { faDiscord } from '@fortawesome/free-brands-svg-icons'; 6 | import { useStoreState } from 'easy-peasy'; 7 | import { ApplicationStore } from '@/state'; 8 | import SearchContainer from '@/components/dashboard/search/SearchContainer'; 9 | import tw, { theme } from 'twin.macro'; 10 | import styled from 'styled-components/macro'; 11 | 12 | const Navigation = styled.div` 13 | ${tw`w-full bg-neutral-900 shadow-md overflow-x-auto`}; 14 | 15 | & > div { 16 | ${tw`mx-auto w-full flex items-center`}; 17 | } 18 | 19 | & #logo { 20 | ${tw`flex-1`}; 21 | 22 | & > a { 23 | ${tw`text-2xl font-header px-4 no-underline text-neutral-200 hover:text-neutral-100 transition-colors duration-150`}; 24 | } 25 | } 26 | `; 27 | 28 | const RightNavigation = styled.div` 29 | ${tw`flex h-full items-center justify-center`}; 30 | 31 | & > a, & > .navigation-link { 32 | ${tw`flex items-center h-full no-underline text-neutral-300 px-6 cursor-pointer transition-all duration-150`}; 33 | 34 | &:active, &:hover { 35 | ${tw`text-neutral-100 bg-black`}; 36 | } 37 | 38 | &:active, &:hover, &.active { 39 | box-shadow: inset 0 -2px ${theme`colors.cyan.700`.toString()}; 40 | } 41 | } 42 | `; 43 | 44 | export default () => { 45 | const name = useStoreState((state: ApplicationStore) => state.settings.data!.name); 46 | const rootAdmin = useStoreState((state: ApplicationStore) => state.user.data!.rootAdmin); 47 | 48 | return ( 49 | 50 |
51 |
52 | 53 | {name} 54 | 55 |
56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | {rootAdmin && 68 | 69 | 70 | 71 | } 72 | 73 | 74 | 75 | 76 |
77 |
78 | ); 79 | }; 80 | -------------------------------------------------------------------------------- /whitelight/tailwind.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | theme: { 3 | fontFamily: { 4 | sans: [ 'Rubik', '-apple-system', 'BlinkMacSystemFont', '"Helvetica Neue"', '"Roboto"', 'system-ui', 'sans-serif' ], 5 | header: [ '"IBM Plex Sans"', '"Roboto"', 'system-ui', 'sans-serif' ], 6 | mono: [ '"IBM Plex Mono"', '"Source Code Pro"', 'SourceCodePro', 'Menlo', 'Monaco', 'Consolas', 'monospace' ], 7 | }, 8 | colors: { 9 | transparent: 'transparent', 10 | black: 'hsl(210, 27%, 10%)', 11 | white: '#ffffff', 12 | primary: { 13 | 50: 'hsl(49, 100%, 96%)', 14 | 100: 'hsl(48, 100%, 88%)', 15 | 200: 'hsl(48, 95%, 76%)', 16 | 300: 'hsl(48, 94%, 68%)', 17 | 400: 'hsl(44, 92%, 63%)', 18 | 500: 'hsl(42, 87%, 55%)', 19 | 600: 'hsl(36, 77%, 49%)', 20 | 700: 'hsl(29, 80%, 44%)', 21 | 800: 'hsl(22, 82%, 39%)', 22 | 900: 'hsl(15, 86%, 30%)', 23 | }, 24 | neutral: { 25 | 50: 'hsl(210, 24%, 16%)', 26 | 100: 'hsl(209, 20%, 25%)', 27 | 200: 'hsl(209, 18%, 30%)', 28 | 300: 'hsl(209, 14%, 37%)', 29 | 400: 'hsl(211, 12%, 43%)', 30 | 500: 'hsl(211, 10%, 53%)', 31 | 600: 'hsl(211, 13%, 65%)', 32 | 700: 'hsl(210, 16%, 82%)', 33 | 800: 'hsl(214, 15%, 91%)', 34 | 900: 'hsl(216, 33%, 97%)', 35 | }, 36 | red: { 37 | 50: 'hsl(360, 100%, 95%)', 38 | 100: 'hsl(360, 100%, 87%)', 39 | 200: 'hsl(360, 100%, 80%)', 40 | 300: 'hsl(360, 91%, 69%)', 41 | 400: 'hsl(360, 83%, 62%)', 42 | 500: 'hsl(356, 75%, 53%)', 43 | 600: 'hsl(354, 85%, 44%)', 44 | 700: 'hsl(352, 90%, 35%)', 45 | 800: 'hsl(350, 94%, 28%)', 46 | 900: 'hsl(348, 94%, 20%)', 47 | }, 48 | yellow: { 49 | 50: 'hsl(49, 100%, 96%)', 50 | 100: 'hsl(48, 100%, 88%)', 51 | 200: 'hsl(48, 95%, 76%)', 52 | 300: 'hsl(48, 94%, 68%)', 53 | 400: 'hsl(44, 92%, 63%)', 54 | 500: 'hsl(42, 87%, 55%)', 55 | 600: 'hsl(36, 77%, 49%)', 56 | 700: 'hsl(29, 80%, 44%)', 57 | 800: 'hsl(22, 82%, 39%)', 58 | 900: 'hsl(15, 86%, 30%)', 59 | }, 60 | cyan: { 61 | 50: 'hsl(171, 82%, 94%)', 62 | 100: 'hsl(172, 97%, 88%)', 63 | 200: 'hsl(174, 96%, 78%)', 64 | 300: 'hsl(176, 87%, 67%)', 65 | 400: 'hsl(178, 78%, 57%)', 66 | 500: 'hsl(180, 77%, 47%)', 67 | 600: 'hsl(182, 85%, 39%)', 68 | 700: 'hsl(184, 90%, 34%)', 69 | 800: 'hsl(186, 91%, 29%)', 70 | 900: 'hsl(188, 91%, 23%)', 71 | }, 72 | green: { 73 | 50: 'hsl(125, 65%, 93%)', 74 | 100: 'hsl(127, 65%, 85%)', 75 | 200: 'hsl(124, 63%, 74%)', 76 | 300: 'hsl(123, 53%, 55%)', 77 | 400: 'hsl(123, 57%, 45%)', 78 | 500: 'hsl(122, 73%, 35%)', 79 | 600: 'hsl(122, 80%, 29%)', 80 | 700: 'hsl(125, 79%, 26%)', 81 | 800: 'hsl(125, 86%, 20%)', 82 | 900: 'hsl(125, 97%, 14%)', 83 | }, 84 | }, 85 | extend: { 86 | fontSize: { 87 | '2xs': '0.625rem', 88 | }, 89 | transitionDuration: { 90 | 250: '250ms', 91 | }, 92 | borderColor: theme => ({ 93 | default: theme('colors.neutral.400', 'currentColor'), 94 | }), 95 | }, 96 | }, 97 | plugins: [ 98 | require('@tailwindcss/forms'), 99 | ] 100 | }; 101 | -------------------------------------------------------------------------------- /JustAtheme/GlobalStylesheet.ts: -------------------------------------------------------------------------------- 1 | import tw from 'twin.macro'; 2 | import { createGlobalStyle } from 'styled-components/macro'; 3 | 4 | export default createGlobalStyle` 5 | body { 6 | ${tw`font-sans bg-neutral-800 text-white`}; 7 | letter-spacing: 0.015em; 8 | } 9 | 10 | h1, h2, h3, h4, h5, h6 { 11 | ${tw`font-medium tracking-normal font-header`}; 12 | } 13 | 14 | p { 15 | ${tw`text-white leading-snug font-sans`}; 16 | } 17 | 18 | form { 19 | ${tw`m-0`}; 20 | } 21 | 22 | textarea, select, input, button, button:focus, button:focus-visible { 23 | ${tw`outline-none`}; 24 | } 25 | 26 | input[type=number]::-webkit-outer-spin-button, 27 | input[type=number]::-webkit-inner-spin-button { 28 | -webkit-appearance: none !important; 29 | margin: 0; 30 | } 31 | 32 | input[type=number] { 33 | -moz-appearance: textfield !important; 34 | } 35 | 36 | /* Scroll Bar Style */ 37 | ::-webkit-scrollbar { 38 | background: none; 39 | width: 16px; 40 | height: 16px; 41 | } 42 | 43 | ::-webkit-scrollbar-thumb { 44 | border: solid 0 rgb(0 0 0 / 0%); 45 | border-right-width: 4px; 46 | border-left-width: 4px; 47 | -webkit-border-radius: 9px 4px; 48 | -webkit-box-shadow: inset 0 0 0 1px rgb(114, 137, 218), inset 0 0 0 4px rgb(114, 137, 218); 49 | } 50 | 51 | ::-webkit-scrollbar-track-piece { 52 | margin: 4px 0; 53 | } 54 | 55 | ::-webkit-scrollbar-thumb:horizontal { 56 | border-right-width: 0; 57 | border-left-width: 0; 58 | border-top-width: 4px; 59 | border-bottom-width: 4px; 60 | -webkit-border-radius: 4px 9px; 61 | } 62 | 63 | ::-webkit-scrollbar-thumb:hover { 64 | -webkit-box-shadow: 65 | inset 0 0 0 1px rgb(171, 184, 232), 66 | inset 0 0 0 4px rgb(171, 184, 232); 67 | } 68 | 69 | ::-webkit-scrollbar-corner { 70 | background: transparent; 71 | } 72 | @media only screen and (max-width: 768px) { 73 | .NavText, 74 | .CreditText, 75 | .fileButtonModal { 76 | display: none; 77 | } 78 | .ServerContentBlock, 79 | .OverviewContainer, 80 | .ApiContainer, 81 | .ConsoleContainer, 82 | .EditContainer, 83 | .editModal { 84 | padding-left: 3.5rem; 85 | } 86 | } 87 | 88 | .xterm, 89 | .xterm-screen, 90 | .xterm .xterm-viewport::-webkit-scrollbar, 91 | .xterm-viewport { 92 | ${tw`bg-neutral-900`}; 93 | } 94 | 95 | input:focus, 96 | select:focus, 97 | textarea:focus, 98 | button:focus { 99 | box-shadow: none !important; 100 | -moz-box-shadow: none !important; 101 | -webkit-box-shadow: none !important; 102 | } 103 | 104 | *, 105 | p, 106 | a, 107 | html, 108 | body, 109 | code { 110 | font-weight: 600; 111 | font-family: 'Poppinns', '-apple-system', 'BlinkMacSystemFont', '"Helvetica Neue"', '"Roboto"', 'system-ui', 'sans-serif'; 112 | } 113 | 114 | .RowSpinner { 115 | justify-content: center !important; 116 | } 117 | 118 | @media only screen and (max-width: 640px) { 119 | .detailsTwo { 120 | display: none !important; 121 | } 122 | 123 | .detailsOne { 124 | max-width: 100% !important; 125 | } 126 | 127 | .KillButton { 128 | display: none !important; 129 | } 130 | 131 | .PowerControlButtons { 132 | transform: scale(.8); 133 | margin-right: 0 !important; 134 | padding-right: 0 !important; 135 | padding-left: 0 !important; 136 | } 137 | } 138 | 139 | .cm-s-ayu-mirage .CodeMirror-linenumber { 140 | color: white !important; 141 | } 142 | 143 | .CodeMirror-gutters, 144 | .CodeMirror-lines, 145 | .CodeMirror-overlayscroll-vertical, 146 | .CodeMirror-foldgutter, 147 | .CodeMirror-gutter, 148 | .CodeMirror-scroll, 149 | .xterm-viewport { 150 | background: #202226 !important; 151 | } 152 | 153 | [type='checkbox']:checked { 154 | background: #7289DA !important; 155 | } 156 | `; 157 | -------------------------------------------------------------------------------- /navy-theme/tailwind.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | theme: { 3 | fontFamily: { 4 | sans: [ 'Poppinns', '-apple-system', 'BlinkMacSystemFont', '"Helvetica Neue"', '"Roboto"', 'system-ui', 'sans-serif' ], 5 | header: [ '"Poppinns"', '"Poppinns"', 'system-ui', 'sans-serif' ], 6 | mono: [ '"Poppinns"', '"Source Code Pro"', 'SourceCodePro', 'Menlo', 'Monaco', 'Consolas', 'monospace' ], 7 | }, 8 | colors: { 9 | transparent: 'transparent', 10 | black: 'hsl(210, 27%, 10%)', 11 | white: '#ffffff', 12 | primary: { 13 | 50: 'hsl(202, 100%, 95%)', // lightest 14 | 100: 'hsl(204, 100%, 86%)', // lighter 15 | 200: 'hsl(206, 93%, 73%)', 16 | 300: 'hsl(208, 88%, 62%)', 17 | 400: 'hsl(210, 83%, 53%)', // light 18 | 500: 'hsl(212, 92%, 43%)', // base 19 | 600: 'hsl(214, 95%, 36%)', // dark 20 | 700: '#08072b', 21 | 800: 'hsl(216, 98%, 25%)', // darker 22 | 900: 'hsl(218, 100%, 17%)', // darkest 23 | }, 24 | neutral: { 25 | 50: 'hsl(216, 33%, 97%)', 26 | 100: 'hsl(214, 15%, 91%)', 27 | 200: 'hsl(210, 16%, 82%)', 28 | 300: '#fafafa', 29 | 400: '#fafafa', 30 | 500: '#fafafa', 31 | 600: 'hsl(209, 14%, 37%)', 32 | 700: '#121124', 33 | 800: '#121124', 34 | 900: '#17627a', 35 | 905: '#171530', 36 | 910: '#08072b', 37 | }, 38 | red: { 39 | 50: 'hsl(360, 100%, 95%)', 40 | 100: 'hsl(360, 100%, 87%)', 41 | 200: 'hsl(360, 100%, 80%)', 42 | 300: 'hsl(360, 91%, 69%)', 43 | 400: 'hsl(360, 83%, 62%)', 44 | 500: 'hsl(356, 75%, 53%)', 45 | 600: 'hsl(354, 85%, 44%)', 46 | 700: '#08072b', 47 | 800: 'hsl(350, 94%, 28%)', 48 | 900: 'hsl(348, 94%, 20%)', 49 | 910: '#ff0307', 50 | }, 51 | yellow: { 52 | 50: 'hsl(49, 100%, 96%)', 53 | 100: 'hsl(48, 100%, 88%)', 54 | 200: 'hsl(48, 95%, 76%)', 55 | 300: 'hsl(48, 94%, 68%)', 56 | 400: 'hsl(44, 92%, 63%)', 57 | 500: 'hsl(42, 87%, 55%)', 58 | 600: 'hsl(36, 77%, 49%)', 59 | 700: '#08072b', 60 | 800: 'hsl(22, 82%, 39%)', 61 | 900: 'hsl(15, 86%, 30%)', 62 | 910: '#f4ff20', 63 | }, 64 | cyan: { 65 | 50: 'hsl(171, 82%, 94%)', 66 | 100: 'hsl(172, 97%, 88%)', 67 | 200: 'hsl(174, 96%, 78%)', 68 | 300: 'hsl(176, 87%, 67%)', 69 | 400: 'hsl(178, 78%, 57%)', 70 | 500: 'hsl(180, 77%, 47%)', 71 | 600: 'hsl(182, 85%, 39%)', 72 | 700: '#08072b', 73 | 710: '#AAB8E8', 74 | 800: 'hsl(186, 91%, 29%)', 75 | 900: 'hsl(188, 91%, 23%)', 76 | }, 77 | green: { 78 | 50: 'hsl(125, 65%, 93%)', 79 | 100: 'hsl(127, 65%, 85%)', 80 | 200: 'hsl(124, 63%, 74%)', 81 | 300: 'hsl(123, 53%, 55%)', 82 | 400: 'hsl(123, 57%, 45%)', 83 | 500: 'hsl(122, 73%, 35%)', 84 | 600: 'hsl(122, 80%, 29%)', 85 | 700: 'hsl(125, 79%, 26%)', 86 | 800: 'hsl(125, 86%, 20%)', 87 | 900: 'hsl(125, 97%, 14%)', 88 | 910: '#2bbf26', 89 | }, 90 | }, 91 | extend: { 92 | fontSize: { 93 | '2xs': '0.625rem', 94 | }, 95 | transitionDuration: { 96 | 250: '250ms', 97 | }, 98 | borderColor: theme => ({ 99 | default: theme('colors.neutral.400', 'currentColor'), 100 | }), 101 | }, 102 | }, 103 | plugins: [ 104 | require('@tailwindcss/forms'), 105 | ] 106 | }; 107 | -------------------------------------------------------------------------------- /darkTheme/tailwind.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | theme: { 3 | fontFamily: { 4 | sans: [ 'Poppinns', '-apple-system', 'BlinkMacSystemFont', '"Helvetica Neue"', '"Roboto"', 'system-ui', 'sans-serif' ], 5 | header: [ '"Poppinns"', '"Poppinns"', 'system-ui', 'sans-serif' ], 6 | mono: [ '"Poppinns"', '"Source Code Pro"', 'SourceCodePro', 'Menlo', 'Monaco', 'Consolas', 'monospace' ], 7 | }, 8 | colors: { 9 | transparent: 'transparent', 10 | black: 'hsl(210, 27%, 10%)', 11 | white: '#ffffff', 12 | primary: { 13 | 50: 'hsl(202, 100%, 95%)', // lightest 14 | 100: 'hsl(204, 100%, 86%)', // lighter 15 | 200: 'hsl(206, 93%, 73%)', 16 | 300: 'hsl(208, 88%, 62%)', 17 | 400: 'hsl(210, 83%, 53%)', // light 18 | 500: 'hsl(212, 92%, 43%)', // base 19 | 600: 'hsl(214, 95%, 36%)', // dark 20 | 700: 'hsl(215, 96%, 32%)', 21 | 800: 'hsl(216, 98%, 25%)', // darker 22 | 900: 'hsl(218, 100%, 17%)', // darkest 23 | }, 24 | neutral: { 25 | 50: 'hsl(216, 33%, 97%)', 26 | 100: 'hsl(214, 15%, 91%)', 27 | 200: 'hsl(210, 16%, 82%)', 28 | 300: '#fff', 29 | 400: '#fff', 30 | 500: '#fff', 31 | 600: 'hsl(209, 14%, 37%)', 32 | 700: '#000000', 33 | 800: '#0d0a0a', 34 | 900: '#000000', 35 | 905: '#000000', 36 | 910: '#0d0a0a', 37 | }, 38 | red: { 39 | 50: 'hsl(360, 100%, 95%)', 40 | 100: 'hsl(360, 100%, 87%)', 41 | 200: 'hsl(360, 100%, 80%)', 42 | 300: 'hsl(360, 91%, 69%)', 43 | 400: 'hsl(360, 83%, 62%)', 44 | 500: 'hsl(356, 75%, 53%)', 45 | 600: 'hsl(354, 85%, 44%)', 46 | 700: 'hsl(352, 90%, 35%)', 47 | 800: 'hsl(350, 94%, 28%)', 48 | 900: 'hsl(348, 94%, 20%)', 49 | 910: '#F93F42', 50 | }, 51 | yellow: { 52 | 50: 'hsl(49, 100%, 96%)', 53 | 100: 'hsl(48, 100%, 88%)', 54 | 200: 'hsl(48, 95%, 76%)', 55 | 300: 'hsl(48, 94%, 68%)', 56 | 400: 'hsl(44, 92%, 63%)', 57 | 500: 'hsl(42, 87%, 55%)', 58 | 600: 'hsl(36, 77%, 49%)', 59 | 700: 'hsl(29, 80%, 44%)', 60 | 800: 'hsl(22, 82%, 39%)', 61 | 900: 'hsl(15, 86%, 30%)', 62 | 910: '#FFA420', 63 | }, 64 | cyan: { 65 | 50: 'hsl(171, 82%, 94%)', 66 | 100: 'hsl(172, 97%, 88%)', 67 | 200: 'hsl(174, 96%, 78%)', 68 | 300: 'hsl(176, 87%, 67%)', 69 | 400: 'hsl(178, 78%, 57%)', 70 | 500: 'hsl(180, 77%, 47%)', 71 | 600: 'hsl(182, 85%, 39%)', 72 | 700: '#7289DA', 73 | 710: '#AAB8E8', 74 | 800: 'hsl(186, 91%, 29%)', 75 | 900: 'hsl(188, 91%, 23%)', 76 | }, 77 | green: { 78 | 50: 'hsl(125, 65%, 93%)', 79 | 100: 'hsl(127, 65%, 85%)', 80 | 200: 'hsl(124, 63%, 74%)', 81 | 300: 'hsl(123, 53%, 55%)', 82 | 400: 'hsl(123, 57%, 45%)', 83 | 500: 'hsl(122, 73%, 35%)', 84 | 600: 'hsl(122, 80%, 29%)', 85 | 700: 'hsl(125, 79%, 26%)', 86 | 800: 'hsl(125, 86%, 20%)', 87 | 900: 'hsl(125, 97%, 14%)', 88 | 910: '#47B381', 89 | }, 90 | }, 91 | extend: { 92 | fontSize: { 93 | '2xs': '0.625rem', 94 | }, 95 | transitionDuration: { 96 | 250: '250ms', 97 | }, 98 | borderColor: theme => ({ 99 | default: theme('colors.neutral.400', 'currentColor'), 100 | }), 101 | }, 102 | }, 103 | plugins: [ 104 | require('@tailwindcss/forms'), 105 | ] 106 | }; 107 | -------------------------------------------------------------------------------- /JustAtheme/tailwind.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | theme: { 3 | fontFamily: { 4 | sans: [ 'Poppinns', '-apple-system', 'BlinkMacSystemFont', '"Helvetica Neue"', '"Roboto"', 'system-ui', 'sans-serif' ], 5 | header: [ '"Poppinns"', '"Poppinns"', 'system-ui', 'sans-serif' ], 6 | mono: [ '"Poppinns"', '"Source Code Pro"', 'SourceCodePro', 'Menlo', 'Monaco', 'Consolas', 'monospace' ], 7 | }, 8 | colors: { 9 | transparent: 'transparent', 10 | black: 'hsl(210, 27%, 10%)', 11 | white: '#ffffff', 12 | primary: { 13 | 50: 'hsl(202, 100%, 95%)', // lightest 14 | 100: 'hsl(204, 100%, 86%)', // lighter 15 | 200: 'hsl(206, 93%, 73%)', 16 | 300: 'hsl(208, 88%, 62%)', 17 | 400: 'hsl(210, 83%, 53%)', // light 18 | 500: 'hsl(212, 92%, 43%)', // base 19 | 600: 'hsl(214, 95%, 36%)', // dark 20 | 700: 'hsl(215, 96%, 32%)', 21 | 800: 'hsl(216, 98%, 25%)', // darker 22 | 900: 'hsl(218, 100%, 17%)', // darkest 23 | }, 24 | neutral: { 25 | 50: 'hsl(216, 33%, 97%)', 26 | 100: 'hsl(214, 15%, 91%)', 27 | 200: 'hsl(210, 16%, 82%)', 28 | 300: '#00000', 29 | 400: '#00000', 30 | 500: '#00000', 31 | 600: 'hsl(209, 14%, 37%)', 32 | 700: '#08072b', 33 | 800: '#13193d', 34 | 900: '#09142e', 35 | 905: '#091330', 36 | 910: '#08072b', 37 | }, 38 | red: { 39 | 50: 'hsl(360, 100%, 95%)', 40 | 100: 'hsl(360, 100%, 87%)', 41 | 200: 'hsl(360, 100%, 80%)', 42 | 300: 'hsl(360, 91%, 69%)', 43 | 400: 'hsl(360, 83%, 62%)', 44 | 500: 'hsl(356, 75%, 53%)', 45 | 600: 'hsl(354, 85%, 44%)', 46 | 700: 'hsl(352, 90%, 35%)', 47 | 800: 'hsl(350, 94%, 28%)', 48 | 900: 'hsl(348, 94%, 20%)', 49 | 910: '#ff0307', 50 | }, 51 | yellow: { 52 | 50: 'hsl(49, 100%, 96%)', 53 | 100: 'hsl(48, 100%, 88%)', 54 | 200: 'hsl(48, 95%, 76%)', 55 | 300: 'hsl(48, 94%, 68%)', 56 | 400: 'hsl(44, 92%, 63%)', 57 | 500: 'hsl(42, 87%, 55%)', 58 | 600: 'hsl(36, 77%, 49%)', 59 | 700: 'hsl(29, 80%, 44%)', 60 | 800: 'hsl(22, 82%, 39%)', 61 | 900: 'hsl(15, 86%, 30%)', 62 | 910: '#f4ff20', 63 | }, 64 | cyan: { 65 | 50: 'hsl(171, 82%, 94%)', 66 | 100: 'hsl(172, 97%, 88%)', 67 | 200: 'hsl(174, 96%, 78%)', 68 | 300: 'hsl(176, 87%, 67%)', 69 | 400: 'hsl(178, 78%, 57%)', 70 | 500: 'hsl(180, 77%, 47%)', 71 | 600: 'hsl(182, 85%, 39%)', 72 | 700: '#7289DA', 73 | 710: '#AAB8E8', 74 | 800: 'hsl(186, 91%, 29%)', 75 | 900: 'hsl(188, 91%, 23%)', 76 | }, 77 | green: { 78 | 50: 'hsl(125, 65%, 93%)', 79 | 100: 'hsl(127, 65%, 85%)', 80 | 200: 'hsl(124, 63%, 74%)', 81 | 300: 'hsl(123, 53%, 55%)', 82 | 400: 'hsl(123, 57%, 45%)', 83 | 500: 'hsl(122, 73%, 35%)', 84 | 600: 'hsl(122, 80%, 29%)', 85 | 700: 'hsl(125, 79%, 26%)', 86 | 800: 'hsl(125, 86%, 20%)', 87 | 900: 'hsl(125, 97%, 14%)', 88 | 910: '#2bbf26', 89 | }, 90 | }, 91 | extend: { 92 | fontSize: { 93 | '2xs': '0.625rem', 94 | }, 95 | transitionDuration: { 96 | 250: '250ms', 97 | }, 98 | borderColor: theme => ({ 99 | default: theme('colors.neutral.400', 'currentColor'), 100 | }), 101 | }, 102 | }, 103 | plugins: [ 104 | require('@tailwindcss/forms'), 105 | ] 106 | }; 107 | -------------------------------------------------------------------------------- /upload-tracker/UploadButton.tsx: -------------------------------------------------------------------------------- 1 | import axios from 'axios'; 2 | import getFileUploadUrl from '@/api/server/files/getFileUploadUrl'; 3 | import tw from 'twin.macro'; 4 | import Button from '@/components/elements/Button'; 5 | import React, { useEffect, useRef, useState } from 'react'; 6 | import styled from 'styled-components/macro'; 7 | import { ModalMask } from '@/components/elements/Modal'; 8 | import Fade from '@/components/elements/Fade'; 9 | import useEventListener from '@/plugins/useEventListener'; 10 | import SpinnerOverlay from '@/components/elements/SpinnerOverlay'; 11 | import useFlash from '@/plugins/useFlash'; 12 | import useFileManagerSwr from '@/plugins/useFileManagerSwr'; 13 | import { ServerContext } from '@/state/server'; 14 | import { WithClassname } from '@/components/types'; 15 | import { bytesToHuman } from "@/helpers"; 16 | 17 | const InnerContainer = styled.div` 18 | max-width: 600px; 19 | ${tw`bg-black w-full border-4 border-primary-500 border-dashed rounded p-10 mx-10`} 20 | `; 21 | 22 | export default ({ className }: WithClassname) => { 23 | const fileUploadInput = useRef(null); 24 | const uuid = ServerContext.useStoreState(state => state.server.data!.uuid); 25 | const [visible, setVisible] = useState(false); 26 | const [loading, setLoading] = useState(false); 27 | const [upload, setUpload] = useState({ size: 0, totalSize: 0, progress: 0 }); 28 | const { mutate } = useFileManagerSwr(); 29 | const { clearFlashes, clearAndAddHttpError } = useFlash(); 30 | const directory = ServerContext.useStoreState(state => state.files.directory); 31 | 32 | useEventListener('dragenter', e => { 33 | e.stopPropagation(); 34 | setVisible(true); 35 | }, true); 36 | 37 | useEventListener('dragexit', e => { 38 | e.stopPropagation(); 39 | setVisible(false); 40 | }, true); 41 | 42 | useEffect(() => { 43 | if (!visible) return; 44 | 45 | const hide = () => setVisible(false); 46 | 47 | window.addEventListener('keydown', hide); 48 | return () => { 49 | window.removeEventListener('keydown', hide); 50 | }; 51 | }, [visible]); 52 | 53 | const onFileSubmission = (files: FileList) => { 54 | const form = new FormData(); 55 | Array.from(files).forEach(file => form.append('files', file)); 56 | 57 | setLoading(true); 58 | clearFlashes('files'); 59 | getFileUploadUrl(uuid) 60 | .then(url => axios.post(`${url}&directory=${directory}`, form, { 61 | headers: { 62 | 'Content-Type': 'multipart/form-data', 63 | }, 64 | onUploadProgress: (progressEvent: ProgressEvent) => { 65 | const size = progressEvent.loaded; 66 | const totalSize = progressEvent.total; 67 | const progress = Math.round((progressEvent.loaded / progressEvent.total) * 100); 68 | setUpload({ size, totalSize, progress }); 69 | }, 70 | })) 71 | .then(() => mutate()) 72 | .catch(error => { 73 | console.error(error); 74 | clearAndAddHttpError({ error, key: 'files' }); 75 | }) 76 | .then(() => setVisible(false)) 77 | .then(() => setLoading(false)); 78 | }; 79 | 80 | return ( 81 | <> 82 | 89 | setVisible(false)} 91 | onDragOver={e => e.preventDefault()} 92 | onDrop={e => { 93 | e.preventDefault(); 94 | e.stopPropagation(); 95 | 96 | setVisible(false); 97 | if (!e.dataTransfer?.files.length) return; 98 | 99 | onFileSubmission(e.dataTransfer.files); 100 | }} 101 | > 102 |
103 | 104 |

105 | Drag and drop files to upload. ( You cannot upload folders archive them and unarchive at panel. ) 106 |

107 |
108 |
109 |
110 |
111 | 112 | Uploaded {bytesToHuman(upload.size)} of {bytesToHuman(upload.totalSize)} ({upload.progress}%) 113 | 114 | { 119 | if (!e.currentTarget.files) return; 120 | 121 | onFileSubmission(e.currentTarget.files); 122 | if (fileUploadInput.current) { 123 | fileUploadInput.current.files = null; 124 | } 125 | }} 126 | /> 127 | 137 | 138 | ); 139 | }; 140 | -------------------------------------------------------------------------------- /big-serverRow/ServerRow.tsx: -------------------------------------------------------------------------------- 1 | import React, { memo, useEffect, useRef, useState } from 'react'; 2 | import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; 3 | import { faEthernet, faHdd, faMemory, faMicrochip, faServer, faCircle } from '@fortawesome/free-solid-svg-icons'; 4 | import { Link } from 'react-router-dom'; 5 | import { Server } from '@/api/server/getServer'; 6 | import getServerResourceUsage, { ServerPowerState, ServerStats } from '@/api/server/getServerResourceUsage'; 7 | import { bytesToHuman, megabytesToHuman } from '@/helpers'; 8 | import tw, { TwStyle } from 'twin.macro'; 9 | import GreyRowBox from '@/components/elements/GreyRowBox'; 10 | import Spinner from '@/components/elements/Spinner'; 11 | import styled from 'styled-components/macro'; 12 | import isEqual from 'react-fast-compare'; 13 | import CopyOnClick from '@/components/elements/CopyOnClick'; 14 | import { ServerContext } from '@/state/server'; 15 | import { SocketEvent, SocketRequest } from '@/components/server/events'; 16 | 17 | 18 | const isAlarmState = (current: number, limit: number): boolean => limit > 0 && (current / (limit * 1024 * 1024) >= 0.90); 19 | 20 | const Icon = memo(styled(FontAwesomeIcon) <{ $alarm: boolean }>` 21 | ${props => props.$alarm ? tw`text-red-400` : tw`text-white`}; 22 | `, isEqual); 23 | 24 | const IconDescription = styled.p<{ $alarm: boolean }>` 25 | ${tw`text-sm ml-2`}; 26 | ${props => props.$alarm ? tw`text-white` : tw`text-white`}; 27 | `; 28 | 29 | const StatusIndicatorBox = styled(GreyRowBox) <{ $status: ServerPowerState | undefined }>` 30 | width: 100%; 31 | margin-left: 0 auto; 32 | height: 31rem !important; 33 | display: inline-block; 34 | text-align: center; 35 | 36 | @media only screen and (max-width: 1125px) { 37 | width: 100% !important; 38 | margin-left: 0 auto !important; 39 | } 40 | 41 | & .status-bar { 42 | ${tw`bg-red-500 w-4 h-4 rounded-full transition-all duration-150`}; 43 | 44 | ${({ $status }) => (!$status || $status === 'offline') ? tw`bg-red-910` : ($status === 'running' ? tw`bg-green-910` : tw`bg-yellow-910`)}; 45 | } 46 | `; 47 | 48 | export default ({ server, className }: { server: Server; className?: string }) => { 49 | const interval = useRef(null); 50 | const [isSuspended, setIsSuspended] = useState(server.status === 'suspended'); 51 | const [stats, setStats] = useState(null); 52 | 53 | const getStats = () => getServerResourceUsage(server.uuid) 54 | .then(data => setStats(data)) 55 | .catch(error => console.error(error)); 56 | 57 | useEffect(() => { 58 | setIsSuspended(stats ?.isSuspended || server.status === 'suspended'); 59 | }, [stats ?.isSuspended, server.status]); 60 | 61 | useEffect(() => { 62 | 63 | if (isSuspended) return; 64 | 65 | getStats().then(() => { 66 | // @ts-ignore 67 | interval.current = setInterval(() => getStats(), 30000); 68 | }); 69 | 70 | return () => { 71 | interval.current && clearInterval(interval.current); 72 | }; 73 | }, [isSuspended]); 74 | 75 | const alarms = { cpu: false, memory: false, disk: false }; 76 | if (stats) { 77 | alarms.cpu = server.limits.cpu === 0 ? false : (stats.cpuUsagePercent >= (server.limits.cpu * 0.9)); 78 | alarms.memory = isAlarmState(stats.memoryUsageInBytes, server.limits.memory); 79 | alarms.disk = server.limits.disk === 0 ? false : isAlarmState(stats.diskUsageInBytes, server.limits.disk); 80 | } 81 | 82 | const diskLimit = server.limits.disk !== 0 ? megabytesToHuman(server.limits.disk) : 'Unlimited'; 83 | const memoryLimit = server.limits.memory !== 0 ? megabytesToHuman(server.limits.memory) : 'Unlimited'; 84 | 85 | return ( 86 | 87 |
88 |
89 |
90 |

{server.name}

91 | {!!server.description && 92 |

{server.description}

93 | } 94 |
95 |
96 |
97 | {(!stats || isSuspended) ? 98 | isSuspended ? 99 |
100 | 101 | {server.status === 'suspended' ? 'Suspended' : 'Connection Error'} 102 | 103 |
104 | : 105 | (server.isTransferring || server.status) ? 106 |
107 | 108 | {server.isTransferring ? 109 | 'Transferring' 110 | : 111 | server.status === 'installing' ? 'Installing' : ( 112 | server.status === 'restoring_backup' ? 113 | 'Restoring Backup' 114 | : 115 | 'Unavailable' 116 | ) 117 | } 118 | 119 |
120 | : 121 |
122 | 123 |
124 | : 125 | 126 |
127 |
128 | 129 | 130 | {stats.cpuUsagePercent.toFixed(2)}% 131 | 132 |
133 |
134 |
135 | 136 | 137 | {bytesToHuman(stats.memoryUsageInBytes)} 138 | / {memoryLimit} 139 | 140 |
141 |
142 |
143 |
144 | 145 | 146 | {bytesToHuman(stats.diskUsageInBytes)} 147 | / {diskLimit} 148 | 149 |
150 |
151 |
152 |
153 |
154 | Node: {server.node} 155 |
156 |
157 |
158 | ID: {server.id} 159 |
160 |
161 |
162 |
163 | IP: { 164 | server.allocations.filter(alloc => alloc.isDefault).map(allocation => ( 165 | 166 | {allocation.alias || allocation.ip}:{allocation.port} 167 | 168 | )) 169 | } 170 | 171 |
172 |
173 |
174 |
175 | } 176 |
177 | 178 | ); 179 | }; 180 | --------------------------------------------------------------------------------