diff --git a/package.json b/package.json index a3103cad6..75e5b87b3 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,9 @@ { "name": "pterodactyl-panel", "dependencies": { + "@fortawesome/fontawesome-svg-core": "^1.2.19", + "@fortawesome/free-solid-svg-icons": "^5.9.0", + "@fortawesome/react-fontawesome": "^0.1.4", "@hot-loader/react-dom": "^16.8.6", "axios": "^0.18.0", "brace": "^0.11.1", diff --git a/resources/assets/styles/components/navigation.css b/resources/assets/styles/components/navigation.css index 5b9f07097..58579dda3 100644 --- a/resources/assets/styles/components/navigation.css +++ b/resources/assets/styles/components/navigation.css @@ -1,117 +1,38 @@ -.nav { - @apply .bg-primary-600 .border-b .border-t .border-primary-700; - height: 56px; +#navigation { + @apply .w-full .bg-neutral-900 .shadow-md; - & .logo { - @apply .mr-8 .font-sans .font-thin .text-3xl .text-white .inline-block; - - & a { - color: inherit; - text-decoration: none; - } - - @screen xsx { - @apply .hidden; - } + & > div { + @apply .mx-auto .w-full .flex .items-center; } - & .search-box { - @apply .mr-2; - - & > .search-input { - @apply .text-sm .p-2 .ml-8 .rounded .border .border-primary-600 .bg-white .text-neutral-900 .w-96; - transition: border 150ms ease-in; - - &:focus { - @apply .border-primary-700; - } - - &.has-search-results { - @apply .border-b-0 .rounded-b-none; - } - } - - & .search-results { - @apply .absolute .bg-white .border .border-primary-700 .border-t-0 .rounded .rounded-t-none .p-2 .ml-8 .z-50 .w-96; - - & a { - @apply .block .no-underline .p-2 .rounded; - - &:not(.no-hover):hover { - @apply .bg-neutral-50; - } - } - } - } - - & .menu { - @apply .flex .h-full .items-center; + & #logo { + @apply .flex-1; & > a { - transition: background-color 150ms linear; - @apply .block .flex .self-stretch .items-center .no-underline .text-white .font-light .text-sm .px-5; + @apply .text-2xl .font-header .px-4 .no-underline .text-neutral-200; + transition: color 150ms linear; &:hover { - @apply .bg-primary-700; + @apply .text-neutral-100; + } + } + } + + & .right-navigation { + @apply .flex .h-full .items-center .justify-center; + + & > a { + @apply .flex .items-center .h-full .no-underline .text-neutral-300 .px-6; + transition: background-color 150ms linear, color 150ms linear, box-shadow 150ms ease-in; + + &.active, &:hover { + @apply .text-neutral-100 .bg-black; + box-shadow: inset 0 -2px config('colors.cyan-700'); + } + + &.active { + box-shadow: inset 0 -2px config('colors.cyan-500'); } } } } - -.sidenav { - ul { - @apply .list-reset; - - & li { - @apply .block; - - & > a { - transition: border-left-color 250ms linear, color 250ms linear; - @apply .block .px-4 .py-3 .border-l-3 .border-neutral-100 .no-underline .text-neutral-400 .font-medium; - - &:hover, &.router-link-exact-active, &.router-link-active { - @apply .text-neutral-800; - } - - &.router-link-exact-active, &.router-link-active { - @apply .border-primary-500 .cursor-default; - } - - &::-moz-focus-inner { - @apply .border-none; - } - } - - /** - * Because of how the router works the first sidebar link is always active - * since that is the container for all of the server things. Override the - * style for active links if its the first one and not an exact route match. - */ - &:first-of-type > a { - &.router-link-active:not(.router-link-exact-active) { - @apply .border-neutral-100 .text-neutral-400 .cursor-pointer; - } - } - } - } -} -/* -.sidenav { - @apply .py-2; - - a { - @apply .block .py-3 .px-6 .text-neutral-900 .no-underline .border .border-transparent; - - &:hover, &.router-link-exact-active { - @apply .border-neutral-400 .bg-neutral-50; - - border-left: 1px solid transparent; - border-right: 1px solid transparent; - } - - &.router-link-exact-active + a:hover { - border-top: 1px solid transparent; - } - } -} -*/ diff --git a/resources/scripts/components/App.tsx b/resources/scripts/components/App.tsx index eab411e95..986f47d14 100644 --- a/resources/scripts/components/App.tsx +++ b/resources/scripts/components/App.tsx @@ -2,11 +2,11 @@ import * as React from 'react'; import { hot } from 'react-hot-loader/root'; import { BrowserRouter as Router, Route } from 'react-router-dom'; import AuthenticationRouter from '@/routers/AuthenticationRouter'; -import AccountRouter from '@/routers/AccountRouter'; import ServerOverviewContainer from '@/components/ServerOverviewContainer'; import { StoreProvider } from 'easy-peasy'; import { store } from '@/state'; import TransitionRouter from '@/TransitionRouter'; +import DashboardRouter from '@/routers/DashboardRouter'; interface WindowWithUser extends Window { PterodactylUser?: { @@ -41,9 +41,8 @@ const App = () => {
- + -
diff --git a/resources/scripts/components/NavigationBar.tsx b/resources/scripts/components/NavigationBar.tsx new file mode 100644 index 000000000..85b400c00 --- /dev/null +++ b/resources/scripts/components/NavigationBar.tsx @@ -0,0 +1,35 @@ +import * as React from 'react'; +import { Link, NavLink } from 'react-router-dom'; +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; +import { faLayerGroup } from '@fortawesome/free-solid-svg-icons/faLayerGroup'; +import { faUserCircle } from '@fortawesome/free-solid-svg-icons/faUserCircle'; +import { faSignOutAlt } from '@fortawesome/free-solid-svg-icons/faSignOutAlt'; +import { faSwatchbook } from '@fortawesome/free-solid-svg-icons/faSwatchbook'; + +export default () => ( +
+
+
+ + Pterodactyl + +
+
+ + + + + + + {process.env.NODE_ENV !== 'production' && + + + + } + + + +
+
+
+); diff --git a/resources/scripts/components/account/AccountOverviewContainer.tsx b/resources/scripts/components/dashboard/AccountOverviewContainer.tsx similarity index 76% rename from resources/scripts/components/account/AccountOverviewContainer.tsx rename to resources/scripts/components/dashboard/AccountOverviewContainer.tsx index d88134f2d..e35fb7d61 100644 --- a/resources/scripts/components/account/AccountOverviewContainer.tsx +++ b/resources/scripts/components/dashboard/AccountOverviewContainer.tsx @@ -1,7 +1,7 @@ import * as React from 'react'; import ContentBox from '@/components/elements/ContentBox'; -import UpdatePasswordForm from '@/components/account/forms/UpdatePasswordForm'; -import UpdateEmailAddressForm from '@/components/account/forms/UpdateEmailAddressForm'; +import UpdatePasswordForm from '@/components/dashboard/forms/UpdatePasswordForm'; +import UpdateEmailAddressForm from '@/components/dashboard/forms/UpdateEmailAddressForm'; export default () => { return ( diff --git a/resources/scripts/components/dashboard/DashboardContainer.tsx b/resources/scripts/components/dashboard/DashboardContainer.tsx new file mode 100644 index 000000000..4384da805 --- /dev/null +++ b/resources/scripts/components/dashboard/DashboardContainer.tsx @@ -0,0 +1,7 @@ +import React from 'react'; + +export default () => ( +
+

Dashboard

+
+); diff --git a/resources/scripts/components/account/DesignElementsContainer.tsx b/resources/scripts/components/dashboard/DesignElementsContainer.tsx similarity index 100% rename from resources/scripts/components/account/DesignElementsContainer.tsx rename to resources/scripts/components/dashboard/DesignElementsContainer.tsx diff --git a/resources/scripts/components/account/forms/UpdateEmailAddressForm.tsx b/resources/scripts/components/dashboard/forms/UpdateEmailAddressForm.tsx similarity index 100% rename from resources/scripts/components/account/forms/UpdateEmailAddressForm.tsx rename to resources/scripts/components/dashboard/forms/UpdateEmailAddressForm.tsx diff --git a/resources/scripts/components/account/forms/UpdatePasswordForm.tsx b/resources/scripts/components/dashboard/forms/UpdatePasswordForm.tsx similarity index 100% rename from resources/scripts/components/account/forms/UpdatePasswordForm.tsx rename to resources/scripts/components/dashboard/forms/UpdatePasswordForm.tsx diff --git a/resources/scripts/routers/AccountRouter.tsx b/resources/scripts/routers/AccountRouter.tsx deleted file mode 100644 index 7631d566f..000000000 --- a/resources/scripts/routers/AccountRouter.tsx +++ /dev/null @@ -1,49 +0,0 @@ -import * as React from 'react'; -import { Link, NavLink, Route, RouteComponentProps } from 'react-router-dom'; -import DesignElementsContainer from '@/components/account/DesignElementsContainer'; -import AccountOverviewContainer from '@/components/account/AccountOverviewContainer'; - -export default ({ match }: RouteComponentProps) => ( -
-
-
-
- - Pterodactyl - -
-
- - Dashboard - - - Account - -
-
-
-
- - -
-
-); diff --git a/resources/scripts/routers/DashboardRouter.tsx b/resources/scripts/routers/DashboardRouter.tsx new file mode 100644 index 000000000..62e3ee147 --- /dev/null +++ b/resources/scripts/routers/DashboardRouter.tsx @@ -0,0 +1,17 @@ +import * as React from 'react'; +import { Route, RouteComponentProps } from 'react-router-dom'; +import DesignElementsContainer from '@/components/dashboard/DesignElementsContainer'; +import AccountOverviewContainer from '@/components/dashboard/AccountOverviewContainer'; +import NavigationBar from '@/components/NavigationBar'; +import DashboardContainer from '@/components/dashboard/DashboardContainer'; + +export default ({ match }: RouteComponentProps) => ( +
+ +
+ + + +
+
+); diff --git a/yarn.lock b/yarn.lock index 2541c4cda..974cee7d7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -726,6 +726,29 @@ version "1.0.0" resolved "https://registry.yarnpkg.com/@csstools/sass-import-resolve/-/sass-import-resolve-1.0.0.tgz#32c3cdb2f7af3cd8f0dca357b592e7271f3831b5" +"@fortawesome/fontawesome-common-types@^0.2.19": + version "0.2.19" + resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-0.2.19.tgz#754a0f85e1290858152e1c05700ab502b11197f1" + +"@fortawesome/fontawesome-svg-core@^1.2.19": + version "1.2.19" + resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-1.2.19.tgz#0eca1ce9285c3d99e6e340633ee8f615f9d1a2e0" + dependencies: + "@fortawesome/fontawesome-common-types" "^0.2.19" + +"@fortawesome/free-solid-svg-icons@^5.9.0": + version "5.9.0" + resolved "https://registry.yarnpkg.com/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-5.9.0.tgz#1c73e7bac17417d23f934d83f7fff5b100a7fda9" + dependencies: + "@fortawesome/fontawesome-common-types" "^0.2.19" + +"@fortawesome/react-fontawesome@^0.1.4": + version "0.1.4" + resolved "https://registry.yarnpkg.com/@fortawesome/react-fontawesome/-/react-fontawesome-0.1.4.tgz#18d61d9b583ca289a61aa7dccc05bd164d6bc9ad" + dependencies: + humps "^2.0.1" + prop-types "^15.5.10" + "@hot-loader/react-dom@^16.8.6": version "16.8.6" resolved "https://registry.yarnpkg.com/@hot-loader/react-dom/-/react-dom-16.8.6.tgz#7923ba27db1563a7cc48d4e0b2879a140df461ea" @@ -3772,6 +3795,10 @@ https-browserify@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73" +humps@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/humps/-/humps-2.0.1.tgz#dd02ea6081bd0568dc5d073184463957ba9ef9aa" + iconv-lite@0.4.23, iconv-lite@^0.4.22, iconv-lite@^0.4.4: version "0.4.23" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.23.tgz#297871f63be507adcfbfca715d0cd0eed84e9a63" @@ -6059,7 +6086,7 @@ promise@^7.1.1: dependencies: asap "~2.0.3" -prop-types@^15.6.1, prop-types@^15.6.2: +prop-types@^15.5.10, prop-types@^15.6.1, prop-types@^15.6.2: version "15.7.2" resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5" dependencies: