Reorganize things, add sidebar and topbar
This commit is contained in:
parent
f3a0b7bc4f
commit
2ba1f46149
@ -14,7 +14,7 @@
|
|||||||
// You should have received a copy of the GNU Affero General Public License
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
import React, { Component } from "react"
|
import React, { Component } from "react"
|
||||||
import Spinner from "./Spinner"
|
import Spinner from "./components/Spinner"
|
||||||
import api from "./api"
|
import api from "./api"
|
||||||
|
|
||||||
class Login extends Component {
|
class Login extends Component {
|
||||||
|
@ -14,11 +14,11 @@
|
|||||||
// You should have received a copy of the GNU Affero General Public License
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
import React, { Component } from "react"
|
import React, { Component } from "react"
|
||||||
import { BrowserRouter as Router, Route, Redirect } from "react-router-dom"
|
import { BrowserRouter as Router, Switch } from "react-router-dom"
|
||||||
import PrivateRoute from "./PrivateRoute"
|
import PrivateRoute from "./components/PrivateRoute"
|
||||||
import Home from "./Home"
|
import Dashboard from "./dashboard"
|
||||||
import Login from "./Login"
|
import Login from "./Login"
|
||||||
import Spinner from "./Spinner"
|
import Spinner from "./components/Spinner"
|
||||||
import api from "./api"
|
import api from "./api"
|
||||||
|
|
||||||
class MaubotRouter extends Component {
|
class MaubotRouter extends Component {
|
||||||
@ -43,6 +43,8 @@ class MaubotRouter extends Component {
|
|||||||
if (username) {
|
if (username) {
|
||||||
localStorage.username = username
|
localStorage.username = username
|
||||||
this.setState({ authed: true })
|
this.setState({ authed: true })
|
||||||
|
} else {
|
||||||
|
localStorage.accessToken = undefined
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error(err)
|
console.error(err)
|
||||||
@ -60,10 +62,11 @@ class MaubotRouter extends Component {
|
|||||||
}
|
}
|
||||||
return <Router>
|
return <Router>
|
||||||
<div className={`maubot-wrapper ${this.state.authed ? "authenticated" : ""}`}>
|
<div className={`maubot-wrapper ${this.state.authed ? "authenticated" : ""}`}>
|
||||||
<Route path="/" exact render={() => <Redirect to={{ pathname: "/dashboard" }}/>}/>
|
<Switch>
|
||||||
<PrivateRoute path="/dashboard" component={Home} authed={this.state.authed}/>
|
<PrivateRoute path="/login" render={() => <Login onLogin={this.login}/>}
|
||||||
<PrivateRoute path="/login" render={() => <Login onLogin={this.login}/>}
|
authed={!this.state.authed} to="/"/>
|
||||||
authed={!this.state.authed} to="/dashboard"/>
|
<PrivateRoute path="/" component={Dashboard} authed={this.state.authed}/>
|
||||||
|
</Switch>
|
||||||
</div>
|
</div>
|
||||||
</Router>
|
</Router>
|
||||||
}
|
}
|
||||||
|
30
maubot/management/frontend/src/dashboard/client/ListEntry.js
Normal file
30
maubot/management/frontend/src/dashboard/client/ListEntry.js
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
// 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 <https://www.gnu.org/licenses/>.
|
||||||
|
import React from "react"
|
||||||
|
import { Link } from "react-router-dom"
|
||||||
|
import { ReactComponent as ChevronRight } from "../../res/chevron-right.svg"
|
||||||
|
|
||||||
|
const ClientListEntry = ({ client }) => (
|
||||||
|
<Link className="client entry" to={`/client/${client.id}`}>
|
||||||
|
<img className="avatar"
|
||||||
|
src={`${client.homeserver}/_matrix/media/r0/download/${client.avatar_url.substr("mxc://".length)}`}
|
||||||
|
alt={client.id.substr(1, 1)}/>
|
||||||
|
<span className="displayname">{client.displayname || client.id}</span>
|
||||||
|
<ChevronRight/>
|
||||||
|
</Link>
|
||||||
|
)
|
||||||
|
|
||||||
|
export default ClientListEntry
|
@ -15,12 +15,10 @@
|
|||||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
import React, { Component } from "react"
|
import React, { Component } from "react"
|
||||||
|
|
||||||
class Home extends Component {
|
class ClientView extends Component {
|
||||||
render() {
|
render() {
|
||||||
return <main>
|
return <div>{this.props.client.displayname}</div>
|
||||||
Hello, {localStorage.username}
|
|
||||||
</main>
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default Home
|
export default ClientView
|
105
maubot/management/frontend/src/dashboard/index.js
Normal file
105
maubot/management/frontend/src/dashboard/index.js
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
// 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 <https://www.gnu.org/licenses/>.
|
||||||
|
import React, { Component } from "react"
|
||||||
|
import { Route, Redirect } from "react-router-dom"
|
||||||
|
import api from "../api"
|
||||||
|
import InstanceListEntry from "./instance/ListEntry"
|
||||||
|
import InstanceView from "./instance/View"
|
||||||
|
import ClientListEntry from "./client/ListEntry"
|
||||||
|
import ClientView from "./client/View"
|
||||||
|
import PluginListEntry from "./plugin/ListEntry"
|
||||||
|
import PluginView from "./plugin/View"
|
||||||
|
|
||||||
|
class Dashboard extends Component {
|
||||||
|
constructor(props) {
|
||||||
|
super(props)
|
||||||
|
this.state = {
|
||||||
|
instances: {},
|
||||||
|
clients: {},
|
||||||
|
plugins: {},
|
||||||
|
}
|
||||||
|
global.maubot = this
|
||||||
|
}
|
||||||
|
|
||||||
|
async componentWillMount() {
|
||||||
|
const [instanceList, clientList, pluginList] = await Promise.all([
|
||||||
|
api.getInstances(), api.getClients(), api.getPlugins()])
|
||||||
|
const instances = {}
|
||||||
|
for (const instance of instanceList) {
|
||||||
|
instances[instance.id] = instance
|
||||||
|
}
|
||||||
|
const clients = {}
|
||||||
|
for (const client of clientList) {
|
||||||
|
clients[client.id] = client
|
||||||
|
}
|
||||||
|
const plugins = {}
|
||||||
|
for (const plugin of pluginList) {
|
||||||
|
plugins[plugin.id] = plugin
|
||||||
|
}
|
||||||
|
this.setState({ instances, clients, plugins })
|
||||||
|
}
|
||||||
|
|
||||||
|
renderList(field, type) {
|
||||||
|
return Object.values(this.state[field + "s"]).map(entry =>
|
||||||
|
React.createElement(type, { key: entry.id, [field]: entry }))
|
||||||
|
}
|
||||||
|
|
||||||
|
renderView(field, type, id) {
|
||||||
|
const entry = this.state[field + "s"][id]
|
||||||
|
if (!entry) {
|
||||||
|
return "Not found :("
|
||||||
|
}
|
||||||
|
return React.createElement(type, { [field]: entry })
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return <div className="dashboard">
|
||||||
|
<div className="title">
|
||||||
|
<img src="/favicon.png" alt=""/>
|
||||||
|
Maubot Manager
|
||||||
|
</div>
|
||||||
|
<div className="topbar">
|
||||||
|
{localStorage.username}
|
||||||
|
</div>
|
||||||
|
<nav className="sidebar">
|
||||||
|
<div className="instances list">
|
||||||
|
<h3 className="title">Instances</h3>
|
||||||
|
{this.renderList("instance", InstanceListEntry)}
|
||||||
|
</div>
|
||||||
|
<div className="clients list">
|
||||||
|
<h3 className="title">Clients</h3>
|
||||||
|
{this.renderList("client", ClientListEntry)}
|
||||||
|
</div>
|
||||||
|
<div className="plugins list">
|
||||||
|
<h3 className="title">Plugins</h3>
|
||||||
|
{this.renderList("plugin", PluginListEntry)}
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
<main>
|
||||||
|
<Route path="/" exact render={() => "Hello, World!"}/>
|
||||||
|
<Route path="/instance/:id" render={({ match }) =>
|
||||||
|
this.renderView("instance", InstanceView, match.params.id)}/>
|
||||||
|
<Route path="/client/:id" render={({ match }) =>
|
||||||
|
this.renderView("client", ClientView, match.params.id)}/>
|
||||||
|
<Route path="/plugin/:id" render={({ match }) =>
|
||||||
|
this.renderView("plugin", PluginView, match.params.id)}/>
|
||||||
|
<Route render={() => <Redirect to={{ pathname: "/" }}/>}/>
|
||||||
|
</main>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Dashboard
|
@ -0,0 +1,27 @@
|
|||||||
|
// 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 <https://www.gnu.org/licenses/>.
|
||||||
|
import React from "react"
|
||||||
|
import { Link } from "react-router-dom"
|
||||||
|
import { ReactComponent as ChevronRight } from "../../res/chevron-right.svg"
|
||||||
|
|
||||||
|
const InstanceListEntry = ({ instance }) => (
|
||||||
|
<Link className="instance entry" to={`/instance/${instance.id}`}>
|
||||||
|
<span className="id">{instance.id}</span>
|
||||||
|
<ChevronRight/>
|
||||||
|
</Link>
|
||||||
|
)
|
||||||
|
|
||||||
|
export default InstanceListEntry
|
24
maubot/management/frontend/src/dashboard/instance/View.js
Normal file
24
maubot/management/frontend/src/dashboard/instance/View.js
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
// 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 <https://www.gnu.org/licenses/>.
|
||||||
|
import React, { Component } from "react"
|
||||||
|
|
||||||
|
class InstanceView extends Component {
|
||||||
|
render() {
|
||||||
|
return <div>{this.props.instance.id}</div>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default InstanceView
|
27
maubot/management/frontend/src/dashboard/plugin/ListEntry.js
Normal file
27
maubot/management/frontend/src/dashboard/plugin/ListEntry.js
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
// 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 <https://www.gnu.org/licenses/>.
|
||||||
|
import React from "react"
|
||||||
|
import { Link } from "react-router-dom"
|
||||||
|
import { ReactComponent as ChevronRight } from "../../res/chevron-right.svg"
|
||||||
|
|
||||||
|
const PluginListEntry = ({ plugin }) => (
|
||||||
|
<Link className="plugin entry" to={`/plugin/${plugin.id}`}>
|
||||||
|
<span className="id">{plugin.id}</span>
|
||||||
|
<ChevronRight/>
|
||||||
|
</Link>
|
||||||
|
)
|
||||||
|
|
||||||
|
export default PluginListEntry
|
24
maubot/management/frontend/src/dashboard/plugin/View.js
Normal file
24
maubot/management/frontend/src/dashboard/plugin/View.js
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
// 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 <https://www.gnu.org/licenses/>.
|
||||||
|
import React, { Component } from "react"
|
||||||
|
|
||||||
|
class PluginView extends Component {
|
||||||
|
render() {
|
||||||
|
return <div>{this.props.plugin.id}</div>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default PluginView
|
1
maubot/management/frontend/src/res/chevron-right.svg
Normal file
1
maubot/management/frontend/src/res/chevron-right.svg
Normal file
@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z"/><path d="M0 0h24v24H0z" fill="none"/></svg>
|
After Width: | Height: | Size: 184 B |
@ -36,9 +36,9 @@
|
|||||||
text-decoration: none
|
text-decoration: none
|
||||||
|
|
||||||
=main-color-button()
|
=main-color-button()
|
||||||
background-color: $main-color
|
background-color: $primary
|
||||||
&:hover
|
&:hover
|
||||||
background-color: $dark-color
|
background-color: $primary-dark
|
||||||
|
|
||||||
.button
|
.button
|
||||||
+button
|
+button
|
||||||
@ -92,7 +92,7 @@
|
|||||||
resize: vertical
|
resize: vertical
|
||||||
|
|
||||||
&:hover, &:focus
|
&:hover, &:focus
|
||||||
border-color: $main-color
|
border-color: $primary
|
||||||
|
|
||||||
&:focus
|
&:focus
|
||||||
border-width: 2px
|
border-width: 2px
|
||||||
@ -101,8 +101,8 @@
|
|||||||
.input, .textarea
|
.input, .textarea
|
||||||
+input
|
+input
|
||||||
|
|
||||||
=notification($color: $error-color)
|
=notification($border: $error-dark, $background: transparentize($error-light, 0.5))
|
||||||
padding: 1rem
|
padding: 1rem
|
||||||
border-radius: .25rem
|
border-radius: .25rem
|
||||||
border: 2px solid $color
|
border: 2px solid $border
|
||||||
background-color: lighten($color, 25%)
|
background-color: $background
|
||||||
|
@ -13,16 +13,18 @@
|
|||||||
//
|
//
|
||||||
// You should have received a copy of the GNU Affero General Public License
|
// You should have received a copy of the GNU Affero General Public License
|
||||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
$main-color: darken(#50D367, 10%)
|
$primary: #00C853
|
||||||
$dark-color: darken($main-color, 10%)
|
$primary-dark: #009624
|
||||||
$light-color: lighten($main-color, 10%)
|
$primary-light: #5EFC82
|
||||||
$alt-color: darken(#47B9D7, 10%)
|
$secondary: #00B8D4
|
||||||
$dark-alt-color: darken($alt-color, 10%)
|
$secondary-dark: #0088A3
|
||||||
$border-color: #CCC
|
$secondary-light: #62EBFF
|
||||||
$error-color: #D35067
|
$error: #B71C1C
|
||||||
|
$error-dark: #7F0000
|
||||||
|
$error-light: #F05545
|
||||||
|
|
||||||
|
$border-color: #DDD
|
||||||
$text-color: #212121
|
$text-color: #212121
|
||||||
$background-color: #FAFAFA
|
$background-color: #FAFAFA
|
||||||
$inverted-text-color: $background-color
|
$inverted-text-color: $background-color
|
||||||
$font-stack: sans-serif
|
$font-stack: sans-serif
|
||||||
$max-width: 42.5rem
|
|
||||||
$header-height: 3.5rem
|
|
||||||
|
@ -20,3 +20,4 @@
|
|||||||
@import base/elements
|
@import base/elements
|
||||||
|
|
||||||
@import pages/login
|
@import pages/login
|
||||||
|
@import pages/dashboard
|
||||||
|
@ -0,0 +1,6 @@
|
|||||||
|
.dashboard {
|
||||||
|
grid-template:
|
||||||
|
[row1-start] "title topbar" 3.5rem [row1-end]
|
||||||
|
[row2-start] "sidebar main" auto [row2-end]
|
||||||
|
/ 15rem auto;
|
||||||
|
}
|
57
maubot/management/frontend/src/style/pages/dashboard.sass
Normal file
57
maubot/management/frontend/src/style/pages/dashboard.sass
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
// 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 <https://www.gnu.org/licenses/>.
|
||||||
|
@import "dashboard-grid"
|
||||||
|
|
||||||
|
.dashboard
|
||||||
|
display: grid
|
||||||
|
height: 100%
|
||||||
|
|
||||||
|
> .title
|
||||||
|
grid-area: title
|
||||||
|
display: flex
|
||||||
|
align-items: center
|
||||||
|
justify-content: center
|
||||||
|
|
||||||
|
font-size: 1.35rem
|
||||||
|
font-weight: bold
|
||||||
|
|
||||||
|
color: $text-color
|
||||||
|
|
||||||
|
z-index: 1
|
||||||
|
|
||||||
|
background-color: $background-color
|
||||||
|
border-right: 1px solid $primary
|
||||||
|
border-bottom: 1px solid $border-color
|
||||||
|
|
||||||
|
> img
|
||||||
|
max-width: 2rem
|
||||||
|
margin-right: .5rem
|
||||||
|
|
||||||
|
> .topbar
|
||||||
|
grid-area: topbar
|
||||||
|
display: flex
|
||||||
|
align-items: center
|
||||||
|
justify-content: center
|
||||||
|
background-color: $primary
|
||||||
|
width: 110%
|
||||||
|
margin: 0 -5%
|
||||||
|
box-shadow: 0 .25rem .25rem rgba(0, 0, 0, .25)
|
||||||
|
|
||||||
|
|
||||||
|
@import "sidebar"
|
||||||
|
|
||||||
|
> .dashboard
|
||||||
|
grid-area: main
|
@ -15,7 +15,7 @@
|
|||||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
.maubot-wrapper:not(.authenticated)
|
.maubot-wrapper:not(.authenticated)
|
||||||
background-color: $main-color
|
background-color: $primary
|
||||||
|
|
||||||
text-align: center
|
text-align: center
|
||||||
|
|
||||||
@ -29,7 +29,7 @@
|
|||||||
margin-top: 3rem
|
margin-top: 3rem
|
||||||
|
|
||||||
h1
|
h1
|
||||||
color: $main-color
|
color: $primary
|
||||||
margin: 3rem 0
|
margin: 3rem 0
|
||||||
|
|
||||||
input, button
|
input, button
|
||||||
@ -53,5 +53,5 @@
|
|||||||
height: 26.5rem
|
height: 26.5rem
|
||||||
|
|
||||||
.error
|
.error
|
||||||
+notification($error-color)
|
+notification($error)
|
||||||
margin: .5rem 2.5rem
|
margin: .5rem 2.5rem
|
||||||
|
53
maubot/management/frontend/src/style/pages/sidebar.sass
Normal file
53
maubot/management/frontend/src/style/pages/sidebar.sass
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
// 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 <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
> .sidebar
|
||||||
|
grid-area: sidebar
|
||||||
|
background-color: $background-color
|
||||||
|
|
||||||
|
border-right: 1px solid $border-color
|
||||||
|
padding: .5rem
|
||||||
|
|
||||||
|
div.list
|
||||||
|
margin-bottom: 1.5rem
|
||||||
|
|
||||||
|
h3.title
|
||||||
|
margin: 0
|
||||||
|
|
||||||
|
a.entry
|
||||||
|
display: block
|
||||||
|
color: $text-color
|
||||||
|
text-decoration: none
|
||||||
|
|
||||||
|
&:not(:hover) > svg
|
||||||
|
display: none
|
||||||
|
|
||||||
|
> svg
|
||||||
|
float: right
|
||||||
|
|
||||||
|
padding: .25rem
|
||||||
|
|
||||||
|
&.client
|
||||||
|
padding: .25rem
|
||||||
|
|
||||||
|
img.avatar
|
||||||
|
max-height: 1.5rem
|
||||||
|
border-radius: 100%
|
||||||
|
vertical-align: middle
|
||||||
|
|
||||||
|
span.displayname
|
||||||
|
margin-left: .25rem
|
||||||
|
vertical-align: middle
|
Loading…
Reference in New Issue
Block a user