diff --git a/maubot/management/frontend/src/components/Switch.js b/maubot/management/frontend/src/components/Switch.js new file mode 100644 index 0000000..975b47c --- /dev/null +++ b/maubot/management/frontend/src/components/Switch.js @@ -0,0 +1,54 @@ +// maubot - A plugin-based Matrix bot system. +// Copyright (C) 2018 Tulir Asokan +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . +import React, { Component } from "react" + +class Switch extends Component { + constructor(props) { + super(props) + this.state = { + active: props.active, + } + } + + componentWillReceiveProps(nextProps) { + this.setState({ + active: nextProps.active, + }) + } + + toggle = () => { + if (this.props.onToggle) { + this.props.onToggle(!this.state.active) + } else { + this.setState({ active: !this.state.active }) + } + } + + render() { + return ( +
+
+ + {this.props.onText || "On"} + {this.props.offText || "Off"} + +
+
+ ) + } +} + +export default Switch diff --git a/maubot/management/frontend/src/dashboard/client/ListEntry.js b/maubot/management/frontend/src/dashboard/client/ListEntry.js deleted file mode 100644 index e19055f..0000000 --- a/maubot/management/frontend/src/dashboard/client/ListEntry.js +++ /dev/null @@ -1,30 +0,0 @@ -// maubot - A plugin-based Matrix bot system. -// Copyright (C) 2018 Tulir Asokan -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . -import React from "react" -import { Link } from "react-router-dom" -import { ReactComponent as ChevronRight } from "../../res/chevron-right.svg" - -const ClientListEntry = ({ client }) => ( - - {client.id.substr(1, - {client.displayname || client.id} - - -) - -export default ClientListEntry diff --git a/maubot/management/frontend/src/index.js b/maubot/management/frontend/src/index.js index cbe10ed..12dd05c 100644 --- a/maubot/management/frontend/src/index.js +++ b/maubot/management/frontend/src/index.js @@ -16,6 +16,6 @@ import React from "react" import ReactDOM from "react-dom" import "./style/index.sass" -import App from "./MaubotRouter" +import App from "./pages/Main" ReactDOM.render(, document.getElementById("root")) diff --git a/maubot/management/frontend/src/Login.js b/maubot/management/frontend/src/pages/Login.js similarity index 97% rename from maubot/management/frontend/src/Login.js rename to maubot/management/frontend/src/pages/Login.js index e342abe..5b97f14 100644 --- a/maubot/management/frontend/src/Login.js +++ b/maubot/management/frontend/src/pages/Login.js @@ -14,8 +14,8 @@ // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . import React, { Component } from "react" -import Spinner from "./components/Spinner" -import api from "./api" +import Spinner from "../components/Spinner" +import api from "../api" class Login extends Component { constructor(props, context) { diff --git a/maubot/management/frontend/src/MaubotRouter.js b/maubot/management/frontend/src/pages/Main.js similarity index 92% rename from maubot/management/frontend/src/MaubotRouter.js rename to maubot/management/frontend/src/pages/Main.js index b3c7561..efb9ac3 100644 --- a/maubot/management/frontend/src/MaubotRouter.js +++ b/maubot/management/frontend/src/pages/Main.js @@ -15,13 +15,13 @@ // along with this program. If not, see . import React, { Component } from "react" import { BrowserRouter as Router, Switch } from "react-router-dom" -import PrivateRoute from "./components/PrivateRoute" +import PrivateRoute from "../components/PrivateRoute" +import Spinner from "../components/Spinner" +import api from "../api" import Dashboard from "./dashboard" import Login from "./Login" -import Spinner from "./components/Spinner" -import api from "./api" -class MaubotRouter extends Component { +class Main extends Component { constructor(props) { super(props) this.state = { @@ -72,4 +72,4 @@ class MaubotRouter extends Component { } } -export default MaubotRouter +export default Main diff --git a/maubot/management/frontend/src/pages/dashboard/Client.js b/maubot/management/frontend/src/pages/dashboard/Client.js new file mode 100644 index 0000000..d352b31 --- /dev/null +++ b/maubot/management/frontend/src/pages/dashboard/Client.js @@ -0,0 +1,114 @@ +// maubot - A plugin-based Matrix bot system. +// Copyright (C) 2018 Tulir Asokan +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . +import React, { Component } from "react" +import { Link } from "react-router-dom" +import Switch from "../../components/Switch" +import { ReactComponent as ChevronRight } from "../../res/chevron-right.svg" +import { ReactComponent as UploadButton } from "../../res/upload.svg" + +function getAvatarURL(client) { + const id = client.avatar_url.substr("mxc://".length) + return `${client.homeserver}/_matrix/media/r0/download/${id}` +} + +const ClientListEntry = ({ client }) => { + const classes = ["client", "entry"] + if (!client.enabled) { + classes.push("disabled") + } else if (!client.started) { + classes.push("stopped") + } + return ( + + {client.id.substr(1, + {client.displayname || client.id} + + + ) +} + +class Client extends Component { + static ListEntry = ClientListEntry + + constructor(props) { + super(props) + this.state = props + } + + componentWillReceiveProps(nextProps) { + this.setState(nextProps) + } + + inputChange = event => { + this.setState({ [event.target.name]: event.target.value }) + } + + render() { + return
+
+ Avatar + +
+
+
+
User ID
+
+ +
+
+
+
Display name
+
+ +
+
+
+
Homeserver
+
+ +
+
+
+
Access token
+
+ +
+
+
+
Sync
+
+ this.setState({ sync })}/> +
+
+
+
Enabled
+
+ this.setState({ enabled })}/> +
+
+
+ +
+ } +} + +export default Client diff --git a/maubot/management/frontend/src/dashboard/index.js b/maubot/management/frontend/src/pages/dashboard/index.js similarity index 92% rename from maubot/management/frontend/src/dashboard/index.js rename to maubot/management/frontend/src/pages/dashboard/index.js index 77ea69b..34dbb0c 100644 --- a/maubot/management/frontend/src/dashboard/index.js +++ b/maubot/management/frontend/src/pages/dashboard/index.js @@ -15,12 +15,11 @@ // along with this program. If not, see . import React, { Component } from "react" import { Route, Switch, Link } from "react-router-dom" -import api from "../api" -import { ReactComponent as Plus } from "../res/plus.svg" +import api from "../../api" +import { ReactComponent as Plus } from "../../res/plus.svg" import InstanceListEntry from "./instance/ListEntry" import InstanceView from "./instance/View" -import ClientListEntry from "./client/ListEntry" -import ClientView from "./client/View" +import Client from "./Client" import PluginListEntry from "./plugin/ListEntry" import PluginView from "./plugin/View" @@ -88,7 +87,7 @@ class Dashboard extends Component {

Clients

- {this.renderList("client", ClientListEntry)} + {this.renderList("client", Client.ListEntry)}
@@ -98,16 +97,16 @@ class Dashboard extends Component { {this.renderList("plugin", PluginListEntry)}
-
+
"Hello, World!"}/> }/> - }/> + }/> }/> this.renderView("instance", InstanceView, match.params.id)}/> - this.renderView("client", ClientView, match.params.id)}/> + this.renderView("client", Client, match.params.id)}/> this.renderView("plugin", PluginView, match.params.id)}/> "Not found :("}/> diff --git a/maubot/management/frontend/src/dashboard/instance/ListEntry.js b/maubot/management/frontend/src/pages/dashboard/instance/ListEntry.js similarity index 92% rename from maubot/management/frontend/src/dashboard/instance/ListEntry.js rename to maubot/management/frontend/src/pages/dashboard/instance/ListEntry.js index 0603e4d..9b36817 100644 --- a/maubot/management/frontend/src/dashboard/instance/ListEntry.js +++ b/maubot/management/frontend/src/pages/dashboard/instance/ListEntry.js @@ -15,7 +15,7 @@ // along with this program. If not, see . import React from "react" import { Link } from "react-router-dom" -import { ReactComponent as ChevronRight } from "../../res/chevron-right.svg" +import { ReactComponent as ChevronRight } from "../../../res/chevron-right.svg" const InstanceListEntry = ({ instance }) => ( diff --git a/maubot/management/frontend/src/dashboard/instance/View.js b/maubot/management/frontend/src/pages/dashboard/instance/View.js similarity index 100% rename from maubot/management/frontend/src/dashboard/instance/View.js rename to maubot/management/frontend/src/pages/dashboard/instance/View.js diff --git a/maubot/management/frontend/src/dashboard/plugin/ListEntry.js b/maubot/management/frontend/src/pages/dashboard/plugin/ListEntry.js similarity index 92% rename from maubot/management/frontend/src/dashboard/plugin/ListEntry.js rename to maubot/management/frontend/src/pages/dashboard/plugin/ListEntry.js index 6facdbf..d7563df 100644 --- a/maubot/management/frontend/src/dashboard/plugin/ListEntry.js +++ b/maubot/management/frontend/src/pages/dashboard/plugin/ListEntry.js @@ -15,7 +15,7 @@ // along with this program. If not, see . import React from "react" import { Link } from "react-router-dom" -import { ReactComponent as ChevronRight } from "../../res/chevron-right.svg" +import { ReactComponent as ChevronRight } from "../../../res/chevron-right.svg" const PluginListEntry = ({ plugin }) => ( diff --git a/maubot/management/frontend/src/dashboard/plugin/View.js b/maubot/management/frontend/src/pages/dashboard/plugin/View.js similarity index 100% rename from maubot/management/frontend/src/dashboard/plugin/View.js rename to maubot/management/frontend/src/pages/dashboard/plugin/View.js diff --git a/maubot/management/frontend/src/res/upload.svg b/maubot/management/frontend/src/res/upload.svg new file mode 100644 index 0000000..f1deea6 --- /dev/null +++ b/maubot/management/frontend/src/res/upload.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/maubot/management/frontend/src/style/base/body.sass b/maubot/management/frontend/src/style/base/body.sass index 462fe8c..ba0406b 100644 --- a/maubot/management/frontend/src/style/base/body.sass +++ b/maubot/management/frontend/src/style/base/body.sass @@ -18,7 +18,6 @@ body margin: 0 padding: 0 font-size: 16px - background-color: $background-color #root position: fixed @@ -33,6 +32,10 @@ body bottom: 0 left: 0 right: 0 + background-color: $background-dark + + > * + background-color: $background .maubot-loading margin-top: 10rem diff --git a/maubot/management/frontend/src/style/base/elements.sass b/maubot/management/frontend/src/style/base/elements.sass index 93d10f0..76f3a4e 100644 --- a/maubot/management/frontend/src/style/base/elements.sass +++ b/maubot/management/frontend/src/style/base/elements.sass @@ -19,7 +19,7 @@ padding: $padding width: $width height: $height - background-color: $background-color + background-color: $background border: none border-radius: .25rem color: $inverted-text-color @@ -28,7 +28,7 @@ cursor: pointer &:hover - background-color: darken($background-color, 10%) + background-color: darken($background, 10%) =link-button() display: inline-block @@ -81,7 +81,7 @@ =input($width: null, $height: null, $vertical-padding: .375rem, $horizontal-padding: 1rem, $font-size: 1rem) font-family: $font-stack border: 1px solid $border-color - background-color: $background-color + background-color: $background color: $text-color width: $width height: $height diff --git a/maubot/management/frontend/src/style/base/vars.sass b/maubot/management/frontend/src/style/base/vars.sass index 6e9a6c3..e179396 100644 --- a/maubot/management/frontend/src/style/base/vars.sass +++ b/maubot/management/frontend/src/style/base/vars.sass @@ -13,6 +13,7 @@ // // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . + $primary: #00C853 $primary-dark: #009624 $primary-light: #5EFC82 @@ -25,6 +26,7 @@ $error-light: #F05545 $border-color: #DDD $text-color: #212121 -$background-color: #FAFAFA -$inverted-text-color: $background-color +$background: #FAFAFA +$background-dark: #E7E7E7 +$inverted-text-color: $background $font-stack: sans-serif diff --git a/maubot/management/frontend/src/style/index.sass b/maubot/management/frontend/src/style/index.sass index c2e9a16..f6b6033 100644 --- a/maubot/management/frontend/src/style/index.sass +++ b/maubot/management/frontend/src/style/index.sass @@ -14,10 +14,10 @@ // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . @import lib/spinner - @import base/vars @import base/body @import base/elements +@import lib/switch @import pages/login @import pages/dashboard diff --git a/maubot/management/frontend/src/style/lib/switch.sass b/maubot/management/frontend/src/style/lib/switch.sass new file mode 100644 index 0000000..c087da4 --- /dev/null +++ b/maubot/management/frontend/src/style/lib/switch.sass @@ -0,0 +1,79 @@ +// maubot - A plugin-based Matrix bot system. +// Copyright (C) 2018 Tulir Asokan +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +.switch + display: flex + + width: 100% + height: 2rem + + cursor: pointer + + border: 1px solid $primary + border-radius: .25rem + background-color: $background + + box-sizing: border-box + + > .box + box-sizing: border-box + width: 50% + height: 100% + + transition: .5s + text-align: center + + color: $inverted-text-color + border-radius: .15rem 0 0 .15rem + background-color: $primary + + align-items: center + + > .text + box-sizing: border-box + width: 100% + + text-align: center + vertical-align: middle + + color: $inverted-text-color + font-size: 1rem + + user-select: none + + .on + display: none + + .off + display: inline + + + &[data-active=true] + > .box + transform: translateX(100%) + + border-radius: 0 .15rem .15rem 0 + background-color: $primary + + .on + display: inline + + .off + display: none + + + + diff --git a/maubot/management/frontend/src/style/pages/client.sass b/maubot/management/frontend/src/style/pages/client.sass new file mode 100644 index 0000000..a6a6f6a --- /dev/null +++ b/maubot/management/frontend/src/style/pages/client.sass @@ -0,0 +1,109 @@ +// maubot - A plugin-based Matrix bot system. +// Copyright (C) 2018 Tulir Asokan +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +> .client + margin: 1rem + + div.avatar-container + position: relative + display: inline-block + width: 8rem + height: 8rem + border-radius: 100% + cursor: pointer + vertical-align: top + + > img.avatar + display: block + max-width: 8rem + max-height: 8rem + border-radius: 100% + position: absolute + left: 50% + top: 50% + -webkit-transform: translateY(-50%) translateX(-50%) + + > svg.upload + position: absolute + display: block + visibility: hidden + + width: 6rem + height: 6rem + + padding: 1rem + + &:hover + > img.avatar + opacity: .25 + + > svg.upload + visibility: visible + + div.info-container + display: inline-table + vertical-align: top + + margin: 1rem 2rem + + > .row + display: table-row + + > .key, > .value + display: table-cell + padding-bottom: .5rem + + > .key + width: 6.5rem + + > .value + margin: .5rem + + > .value > .switch + width: auto + height: 2rem + + > .value > input + border: none + height: 2rem + width: 100% + + box-sizing: border-box + + padding: .375rem 0 + background-color: $background + + font-size: 1rem + + border-bottom: 1px solid transparent + + &:hover:not(:disabled) + border-bottom: 1px solid $primary + + &:focus:not(:disabled) + border-bottom: 2px solid $primary + +//> .client + display: table + + > .field + display: table-row + width: 100% + + > .name, > .value + display: table-cell + width: 50% + text-align: center diff --git a/maubot/management/frontend/src/style/pages/dashboard.sass b/maubot/management/frontend/src/style/pages/dashboard.sass index dd001a0..801fc86 100644 --- a/maubot/management/frontend/src/style/pages/dashboard.sass +++ b/maubot/management/frontend/src/style/pages/dashboard.sass @@ -18,6 +18,9 @@ .dashboard display: grid height: 100% + max-width: 60rem + margin: auto + box-shadow: 0 .5rem .5rem rgba(0, 0, 0, 0.5) > a.title grid-area: title @@ -31,9 +34,7 @@ color: $text-color text-decoration: none - z-index: 1 - - background-color: $background-color + background-color: white border-right: 1px solid $primary border-bottom: 1px solid $border-color @@ -47,12 +48,14 @@ align-items: center justify-content: center background-color: $primary - width: 110% - margin: 0 -5% - box-shadow: 0 .25rem .25rem rgba(0, 0, 0, .25) + box-shadow: 0 .25rem .25rem rgba(0, 0, 0, .2) @import "sidebar" - > main.dashboard + > main.view grid-area: main + + @import "client" + @import "instance" + @import "plugin" diff --git a/maubot/management/frontend/src/dashboard/client/View.js b/maubot/management/frontend/src/style/pages/instance.sass similarity index 80% rename from maubot/management/frontend/src/dashboard/client/View.js rename to maubot/management/frontend/src/style/pages/instance.sass index b63d58f..7847402 100644 --- a/maubot/management/frontend/src/dashboard/client/View.js +++ b/maubot/management/frontend/src/style/pages/instance.sass @@ -13,12 +13,6 @@ // // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . -import React, { Component } from "react" -class ClientView extends Component { - render() { - return
{this.props.displayname}
- } -} - -export default ClientView +> .instance + margin: 1rem diff --git a/maubot/management/frontend/src/style/pages/plugin.sass b/maubot/management/frontend/src/style/pages/plugin.sass new file mode 100644 index 0000000..e1376b5 --- /dev/null +++ b/maubot/management/frontend/src/style/pages/plugin.sass @@ -0,0 +1,18 @@ +// maubot - A plugin-based Matrix bot system. +// Copyright (C) 2018 Tulir Asokan +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +> .plugin + margin: 1rem diff --git a/maubot/management/frontend/src/style/pages/sidebar.sass b/maubot/management/frontend/src/style/pages/sidebar.sass index 47bbfd7..cb48b12 100644 --- a/maubot/management/frontend/src/style/pages/sidebar.sass +++ b/maubot/management/frontend/src/style/pages/sidebar.sass @@ -16,13 +16,16 @@ > .sidebar grid-area: sidebar - background-color: $background-color + background-color: white border-right: 1px solid $border-color padding: .5rem + overflow-y: auto + div.list - margin-bottom: 1.5rem + &:not(:last-of-type) + margin-bottom: 1.5rem div.title h2