kleckrelay/src/route-widgets/AliasDetailRoute/AliasPreferencesForm.tsx

181 lines
4.9 KiB
TypeScript

import * as yup from "yup"
import {ReactElement} from "react"
import {BsImage, BsShieldShaded} from "react-icons/bs"
import {useFormik} from "formik"
import {FaFile} from "react-icons/fa"
import {MdCheckCircle} from "react-icons/md"
import {AxiosError} from "axios"
import {LoadingButton} from "@mui/lab"
import {Collapse, Grid} from "@mui/material"
import {mdiTextBoxMultiple} from "@mdi/js/commonjs/mdi"
import {useMutation} from "@tanstack/react-query"
import Icon from "@mdi/react"
import {Alias, ImageProxyFormatType, ProxyUserAgentType} from "~/server-types"
import {
IMAGE_PROXY_FORMAT_TYPE_NAME_MAP,
IMAGE_PROXY_USER_AGENT_TYPE_NAME_MAP,
} from "~/constants/enum_mappings"
import {UpdateAliasData, updateAlias} from "~/apis"
import {ErrorSnack, SuccessSnack} from "~/components"
import {parseFastAPIError} from "~/utils"
import SelectField from "~/route-widgets/SettingsRoute/SelectField"
export interface AliasPreferencesFormProps {
alias: Alias
}
interface Form {
removeTrackers: boolean | null
createMailReport: boolean | null
proxyImages: boolean | null
imageProxyFormat: ImageProxyFormatType | null
imageProxyUserAgent: ProxyUserAgentType | null
detail?: string
}
const SCHEMA = yup.object().shape({
removeTrackers: yup.mixed<boolean | null>().oneOf([true, false, null]),
createMailReport: yup.mixed<boolean | null>().oneOf([true, false, null]),
proxyImages: yup.mixed<boolean | null>().oneOf([true, false, null]),
imageProxyFormat: yup
.mixed<ImageProxyFormatType>()
.oneOf([null, ...Object.values(ImageProxyFormatType)]),
imageProxyUserAgent: yup
.mixed<ProxyUserAgentType>()
.oneOf([null, ...Object.values(ProxyUserAgentType)]),
})
export default function AliasPreferencesForm({
alias,
}: AliasPreferencesFormProps): ReactElement {
const {mutateAsync, isSuccess} = useMutation<
Alias,
AxiosError,
UpdateAliasData
>(data => updateAlias(alias.id, data))
const formik = useFormik<Form>({
enableReinitialize: true,
initialValues: {
removeTrackers: alias.prefRemoveTrackers,
createMailReport: alias.prefCreateMailReport,
proxyImages: alias.prefProxyImages,
imageProxyFormat: alias.prefImageProxyFormat,
imageProxyUserAgent: alias.prefImageProxyUserAgent,
},
validationSchema: SCHEMA,
onSubmit: async (values, {setErrors}) => {
try {
await mutateAsync({
prefCreateMailReport: values.createMailReport,
prefRemoveTrackers: values.removeTrackers,
prefProxyImages: values.proxyImages,
prefImagProxyFormat: values.imageProxyFormat,
prefImageProxyUserAgent: values.imageProxyUserAgent,
})
} catch (error) {
setErrors(parseFastAPIError(error as AxiosError))
}
},
})
return (
<>
<form onSubmit={formik.handleSubmit}>
<Grid
container
spacing={4}
flexDirection="column"
alignItems="center"
>
<Grid item>
<Grid container spacing={4}>
<Grid item xs={12} sm={6}>
<SelectField
label="Remove Trackers"
formik={formik}
icon={<BsShieldShaded />}
name="removeTrackers"
/>
</Grid>
<Grid item xs={12} sm={6}>
<SelectField
label="Create Reports"
formik={formik}
icon={
<Icon
path={mdiTextBoxMultiple}
size={0.8}
/>
}
name="createMailReport"
/>
</Grid>
<Grid item xs={12}>
<Grid container spacing={2}>
<Grid item xs={12}>
<SelectField
label="Proxy Images"
formik={formik}
icon={<BsImage />}
name="proxyImages"
/>
</Grid>
<Grid item xs={12}>
<Collapse
in={
formik.values.proxyImages !==
false
}
>
<Grid container spacing={4}>
<Grid item xs={12} sm={6}>
<SelectField
label="Image File Type"
formik={formik}
icon={<FaFile />}
name="imageProxyFormat"
valueTextMap={
IMAGE_PROXY_FORMAT_TYPE_NAME_MAP
}
/>
</Grid>
<Grid item xs={12} sm={6}>
<SelectField
label="Image Proxy User Agent"
formik={formik}
name="imageProxyUserAgent"
valueTextMap={
IMAGE_PROXY_USER_AGENT_TYPE_NAME_MAP
}
/>
</Grid>
</Grid>
</Collapse>
</Grid>
</Grid>
</Grid>
</Grid>
</Grid>
<Grid item>
<LoadingButton
loading={formik.isSubmitting}
variant="contained"
type="submit"
startIcon={<MdCheckCircle />}
>
Save Settings
</LoadingButton>
</Grid>
</Grid>
</form>
<ErrorSnack message={formik.errors.detail} />
<SuccessSnack
message={isSuccess && "Updated Alias successfully!"}
/>
</>
)
}