import { isHexColor } from "class-validator"; import { pickBy } from "lodash"; import { observer } from "mobx-react"; import { TeamIcon } from "outline-icons"; import { useRef, useState } from "react"; import * as React from "react"; import { useTranslation, Trans } from "react-i18next"; import { ThemeProvider, useTheme } from "styled-components"; import { buildDarkTheme, buildLightTheme } from "@shared/styles/theme"; import { CustomTheme } from "@shared/types"; import { getBaseDomain } from "@shared/utils/domains"; import Button from "~/components/Button"; import DefaultCollectionInputSelect from "~/components/DefaultCollectionInputSelect"; import Heading from "~/components/Heading"; import Input from "~/components/Input"; import InputColor from "~/components/InputColor"; import Scene from "~/components/Scene"; import Text from "~/components/Text"; import env from "~/env"; import useCurrentTeam from "~/hooks/useCurrentTeam"; import useStores from "~/hooks/useStores"; import useToasts from "~/hooks/useToasts"; import isCloudHosted from "~/utils/isCloudHosted"; import ImageInput from "./components/ImageInput"; import SettingRow from "./components/SettingRow"; function Details() { const { auth, ui } = useStores(); const { showToast } = useToasts(); const { t } = useTranslation(); const team = useCurrentTeam(); const theme = useTheme(); const form = useRef(null); const [accent, setAccent] = useState(team.preferences?.customTheme?.accent); const [accentText, setAccentText] = useState( team.preferences?.customTheme?.accentText ); const [name, setName] = useState(team.name); const [subdomain, setSubdomain] = useState(team.subdomain); const [defaultCollectionId, setDefaultCollectionId] = useState( team.defaultCollectionId ); const customTheme: Partial = pickBy( { accent, accentText, }, isHexColor ); const handleSubmit = React.useCallback( async (event?: React.SyntheticEvent) => { if (event) { event.preventDefault(); } try { await auth.updateTeam({ name, subdomain, defaultCollectionId, preferences: { ...team.preferences, customTheme, }, }); showToast(t("Settings saved"), { type: "success", }); } catch (err) { showToast(err.message, { type: "error", }); } }, [ auth, name, subdomain, defaultCollectionId, team.preferences, customTheme, showToast, t, ] ); const handleNameChange = React.useCallback( (ev: React.ChangeEvent) => { setName(ev.target.value); }, [] ); const handleSubdomainChange = React.useCallback( (ev: React.ChangeEvent) => { setSubdomain(ev.target.value.toLowerCase()); }, [] ); const handleAvatarUpload = async (avatarUrl: string) => { await auth.updateTeam({ avatarUrl, }); showToast(t("Logo updated"), { type: "success", }); }; const handleAvatarError = React.useCallback( (error: string | null | undefined) => { showToast(error || t("Unable to upload new logo")); }, [showToast, t] ); const onSelectCollection = React.useCallback(async (value: string) => { const defaultCollectionId = value === "home" ? null : value; setDefaultCollectionId(defaultCollectionId); }, []); const isValid = form.current?.checkValidity(); const newTheme = React.useMemo( () => ui.resolvedTheme === "light" ? buildLightTheme(customTheme) : buildDarkTheme(customTheme), [customTheme, ui.resolvedTheme] ); return ( }> {t("Details")} These settings affect the way that your knowledge base appears to everyone on the team.
{t("Display")} {t("Behavior")} Your knowledge base will be accessible at{" "} {subdomain}.{getBaseDomain()} ) : ( t( "Choose a subdomain to enable a login page just for your team." ) ) } >
); } export default observer(Details);