import { Button, FormGroup, H1, H2, Intent, NonIdealState, Spinner, Switch } from "@blueprintjs/core"; import { IconNames } from "@blueprintjs/icons"; import { push } from "connected-react-router"; import React from "react"; import { connect } from "react-redux"; import { Redirect } from "react-router"; import { Dispatch } from "redux"; import styled from "styled-components"; import AppToaster from "../../toaster"; import { getAuthToken, getFromApi, postToApi, unsetAuthToken } from "../../util"; import { Page } from "../atoms"; const ButtonContainer = styled.div` display: flex; flex-direction: row; width: 100%; justify-content: space-between; `; interface AdminSettings { domain: string; optIn: boolean; optOut: boolean; userCount: number; statusCount: number; } interface AdminScreenProps { navigate: (path: string) => void; } interface AdminScreenState { settings?: AdminSettings; isUpdating: boolean; } class AdminScreen extends React.PureComponent { private authToken = getAuthToken(); public constructor(props: AdminScreenProps) { super(props); this.state = { isUpdating: false }; } public componentDidMount() { // Load instance settings from server if (this.authToken) { getFromApi(`admin`, this.authToken) .then((response) => { this.setState({ settings: response }); }) .catch(() => { AppToaster.show({ icon: IconNames.ERROR, intent: Intent.DANGER, message: "Failed to load settings.", timeout: 0, }); unsetAuthToken(); }); } } public render() { if (!this.authToken) { return ; } const { settings, isUpdating } = this.state; let content; if (!settings) { content = } />; } else { content = ( <>

{settings.domain}

{`${settings.userCount} users with ${settings.statusCount || "(unknown)"} statuses.`}

{settings.userCount < 10 && ( )}
); } return (

Instance administration

{content}
); } private updateOptIn = (e: React.FormEvent) => { const settings = this.state.settings as AdminSettings; const optIn = e.currentTarget.checked; let { optOut } = settings; if (optIn) { optOut = false; } this.setState({ settings: { ...settings, optIn, optOut } }); }; private updateOptOut = (e: React.FormEvent) => { const settings = this.state.settings as AdminSettings; const optOut = e.currentTarget.checked; let { optIn } = settings; if (optOut) { optIn = false; } this.setState({ settings: { ...settings, optIn, optOut } }); }; private updateSettings = (e: React.FormEvent) => { e.preventDefault(); this.setState({ isUpdating: true }); const body = { optIn: this.state.settings!.optIn, optOut: this.state.settings!.optOut, }; postToApi(`admin`, body, this.authToken!) .then((response) => { this.setState({ settings: response, isUpdating: false }); AppToaster.show({ icon: IconNames.TICK, intent: Intent.SUCCESS, message: "Successfully updated settings.", }); }) .catch(() => { this.setState({ isUpdating: false }); AppToaster.show({ intent: Intent.DANGER, icon: IconNames.ERROR, message: "Failed to update settings." }); }); }; private logout = () => { unsetAuthToken(); AppToaster.show({ icon: IconNames.LOG_OUT, message: "Logged out.", }); this.props.navigate("/admin/login"); }; } const mapDispatchToProps = (dispatch: Dispatch) => ({ navigate: (path: string) => dispatch(push(path)), }); export default connect(undefined, mapDispatchToProps)(AdminScreen);