diff --git a/i18n/en_US.yaml b/i18n/en_US.yaml index 9ff1ea45..97fb1131 100644 --- a/i18n/en_US.yaml +++ b/i18n/en_US.yaml @@ -916,6 +916,7 @@ ui: interface: Interface smtp: SMTP branding: Branding + legal: Legal dashboard: title: Dashboard welcome: Welcome to Answer Admin! @@ -1108,10 +1109,20 @@ ui: smtp_authentication: label: SMTP Authentication msg: SMTP authentication cannot be empty. - 'yes': 'Yes' - 'no': 'No' + "yes": "Yes" + "no": "No" branding: page_title: Branding + legal: + page_title: Legal + terms_of_service: + label: Terms of Service + msg: Terms of service cannot be empty. + text: "You can add terms of service content here. If you already have a document hosted elsewhere, provide the full URL here." + privacy_policy: + label: Privacy Policy + msg: Privacy policy cannot be empty. + text: "You can add privacy policy content here. If you already have a document hosted elsewhere, provide the full URL here." form: empty: cannot be empty invalid: is invalid diff --git a/ui/src/common/constants.ts b/ui/src/common/constants.ts index 3ed5e37c..7bd2fc19 100644 --- a/ui/src/common/constants.ts +++ b/ui/src/common/constants.ts @@ -59,6 +59,8 @@ export const ADMIN_NAV_MENUS = [ { name: 'interface' }, { name: 'branding' }, { name: 'smtp' }, + { name: 'legal' }, + { name: 'write' }, ], }, ]; diff --git a/ui/src/common/interface.ts b/ui/src/common/interface.ts index 9ea391c7..23602e3c 100644 --- a/ui/src/common/interface.ts +++ b/ui/src/common/interface.ts @@ -289,6 +289,16 @@ export interface SiteSettings { interface: AdminSettingsInterface; } +export interface AdminSettingsLegal { + terms_of_service: string; + privacy_policy: string; +} + +export interface AdminSettingsWrite { + recommend_tags: string; + required_tags: string; +} + /** * @description interface for Activity */ diff --git a/ui/src/i18n/locales/en_US.yaml b/ui/src/i18n/locales/en_US.yaml index 293e066b..c0ccbbdd 100644 --- a/ui/src/i18n/locales/en_US.yaml +++ b/ui/src/i18n/locales/en_US.yaml @@ -916,6 +916,8 @@ ui: interface: Interface smtp: SMTP branding: Branding + legal: Legal + write: Write dashboard: title: Dashboard welcome: Welcome to Answer Admin! @@ -1108,22 +1110,29 @@ ui: smtp_authentication: label: SMTP Authentication msg: SMTP authentication cannot be empty. - 'yes': 'Yes' - 'no': 'No' + "yes": "Yes" + "no": "No" branding: page_title: Branding - logo: - label: Logo - text: The logo image at the top left of your site. Use a wide rectangular image with a height of 56 and an aspect ratio greater than 3:1. If left blank, the site title text will be shown. - mobile_logo: - label: Mobile Logo (optional) - text: The logo used on mobile version of your site. Use a wide rectangular image with a height of 56. If left blank, the image from the “logo” setting will be used. - square_icon: - label: Square Icon - text: Image used as the base for metadata icons. Should ideally be larger than 512x512. - favicon: - label: Favicon (optional) - text: A favicon for your site. To work correctly over a CDN it must be a png. Will be resized to 32x32. If left blank, “square icon” will be used. + legal: + page_title: Legal + terms_of_service: + label: Terms of Service + msg: Terms of service cannot be empty. + text: "You can add terms of service content here. If you already have a document hosted elsewhere, provide the full URL here." + privacy_policy: + label: Privacy Policy + msg: Privacy policy cannot be empty. + text: "You can add privacy policy content here. If you already have a document hosted elsewhere, provide the full URL here." + write: + page_title: Write + recommend_tags: + label: Recommend Tags + msg: Recommend tags cannot be empty. + text: "Please input tag slug above, one tag per line." + required_tags: + label: Required Tags + text: "Every new question must have at least one recommend tag" form: empty: cannot be empty invalid: is invalid diff --git a/ui/src/pages/Admin/Legal/index.tsx b/ui/src/pages/Admin/Legal/index.tsx new file mode 100644 index 00000000..1f494bbc --- /dev/null +++ b/ui/src/pages/Admin/Legal/index.tsx @@ -0,0 +1,108 @@ +import React, { FC, useEffect, useState } from 'react'; +import { useTranslation } from 'react-i18next'; + +import { SchemaForm, JSONSchema, initFormData, UISchema } from '@/components'; +import type * as Type from '@/common/interface'; +// import { useToast } from '@/hooks'; +// import { siteInfoStore } from '@/stores'; +import { useGeneralSetting } from '@/services'; + +import '../index.scss'; + +const Legal: FC = () => { + const { t } = useTranslation('translation', { + keyPrefix: 'admin.legal', + }); + // const Toast = useToast(); + // const updateSiteInfo = siteInfoStore((state) => state.update); + + const { data: setting } = useGeneralSetting(); + const schema: JSONSchema = { + title: t('page_title'), + required: ['terms_of_service', 'privacy_policy'], + properties: { + terms_of_service: { + type: 'string', + title: t('terms_of_service.label'), + description: t('terms_of_service.text'), + }, + privacy_policy: { + type: 'string', + title: t('privacy_policy.label'), + description: t('privacy_policy.text'), + }, + }, + }; + const uiSchema: UISchema = { + terms_of_service: { + 'ui:widget': 'textarea', + 'ui:options': { + rows: 10, + }, + }, + privacy_policy: { + 'ui:widget': 'textarea', + 'ui:options': { + rows: 10, + }, + }, + }; + const [formData, setFormData] = useState(initFormData(schema)); + + const onSubmit = (evt) => { + evt.preventDefault(); + evt.stopPropagation(); + + const reqParams: Type.AdminSettingsLegal = { + terms_of_service: formData.terms_of_service.value, + privacy_policy: formData.privacy_policy.value, + }; + + console.log(reqParams); + // updateGeneralSetting(reqParams) + // .then(() => { + // Toast.onShow({ + // msg: t('update', { keyPrefix: 'toast' }), + // variant: 'success', + // }); + // updateSiteInfo(reqParams); + // }) + // .catch((err) => { + // if (err.isError && err.key) { + // formData[err.key].isInvalid = true; + // formData[err.key].errorMsg = err.value; + // } + // setFormData({ ...formData }); + // }); + }; + + useEffect(() => { + if (!setting) { + return; + } + const formMeta = {}; + Object.keys(setting).forEach((k) => { + formMeta[k] = { ...formData[k], value: setting[k] }; + }); + setFormData({ ...formData, ...formMeta }); + }, [setting]); + + const handleOnChange = (data) => { + setFormData(data); + }; + + return ( + <> +