sozsoft-platform/ui/src/views/settings/Settings.tsx

245 lines
8.5 KiB
TypeScript
Raw Normal View History

2026-02-24 20:44:16 +00:00
import { AdaptableCard } from '@/components/shared'
import Container from '@/components/shared/Container'
import {
Button,
Card,
Checkbox,
FormContainer,
FormItem,
Input,
Menu,
Select,
Tooltip,
toast,
} from '@/components/ui'
import Notification from '@/components/ui/Notification'
import { APP_NAME } from '@/constants/app.constant'
import { MainGroupedSettingDto } from '@/proxy/settings/models'
import { getList, updateSettingValues } from '@/services/setting-ui.service'
import { useStoreActions, useStoreState } from '@/store'
2026-03-27 13:49:15 +00:00
import { SelectBoxOption } from '@/types/shared'
2026-02-24 20:44:16 +00:00
import { useLocalization } from '@/utils/hooks/useLocalization'
import { Field, FieldProps, Form, Formik } from 'formik'
import isEmpty from 'lodash/isEmpty'
import { useEffect, useMemo, useState } from 'react'
import { Helmet } from 'react-helmet'
import { FaQuestionCircle } from 'react-icons/fa'
function getOptions(selectOptions?: Record<string, string>) {
2026-03-27 13:49:15 +00:00
const options: SelectBoxOption[] = []
2026-02-24 20:44:16 +00:00
if (!selectOptions) {
return options
}
Object.entries(selectOptions).forEach(([key, value]) =>
options.push({
value: key,
label: value,
}),
)
return options
}
const Settings = () => {
const { translate } = useLocalization()
const [list, setList] = useState<MainGroupedSettingDto[]>([])
const [mainGroups, setMainGroups] = useState<string[]>([])
const [activeMainGroupKey, setActiveMainGroupKey] = useState<string>()
const activeMainGroup = useMemo(
() => list.find((a) => a.groupName === activeMainGroupKey),
[activeMainGroupKey, list],
)
const { getConfig } = useStoreActions((a) => a.abpConfig)
const { setMode } = useStoreActions((actions) => actions.theme)
const onFormSubmit = async (
values: Record<string, string>,
setSubmitting: (isSubmitting: boolean) => void,
activeGroupName?: string,
) => {
//Dark Mode verildimi ?
2026-03-27 13:49:15 +00:00
if (values.App_SiteManagement_Theme_Style) {
2026-02-24 20:44:16 +00:00
setMode(
2026-03-27 13:49:15 +00:00
values.App_SiteManagement_Theme_Style.includes('.dark') ? 'dark' : 'light',
2026-02-24 20:44:16 +00:00
)
}
2026-03-27 13:49:15 +00:00
console.log(values)
2026-02-24 20:44:16 +00:00
const resp = await updateSettingValues(values)
if (resp.status === 204) {
await fetchData(activeGroupName)
toast.push(
<Notification
title={
translate('::' + activeGroupName) +
' ' +
2026-03-27 13:49:15 +00:00
translate('::SuccessfullySaved')
2026-02-24 20:44:16 +00:00
}
type="success"
/>,
{
placement: 'top-end',
},
)
} else {
toast.push(<Notification title={resp?.error?.message} type="danger" />, {
placement: 'top-end',
})
}
//getConfig değiştiriliyor.
getConfig(false)
setSubmitting(false)
}
const mode = useStoreState((state) => state.theme.mode)
const fetchData = async (activeGroupName?: string) => {
const result = await getList()
if (result.data) {
setList(result.data)
if (activeGroupName) {
setActiveMainGroupKey(activeGroupName)
} else {
setActiveMainGroupKey(result.data.length ? result.data[0].groupName : '')
}
setMainGroups(result.data.map((a) => a.groupName))
}
}
useEffect(() => {
if (isEmpty(list)) {
fetchData()
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [])
return (
<Container className="h-full">
<Helmet
titleTemplate={`%s | ${APP_NAME}`}
title={translate('::' + 'App.Settings')}
defaultTitle={APP_NAME}
></Helmet>
<div className="flex flex-col md:flex-row gap-4">
<div className="md:w-2/12 min-w-fit">
<Menu className="p-2" variant={mode} defaultActiveKeys={[activeMainGroupKey ?? '']}>
{mainGroups.map((group) => (
<Menu.MenuItem
key={group}
className="break-all whitespace-normal"
eventKey={group}
onSelect={() => setActiveMainGroupKey(group)}
>
{translate('::' + group)}
</Menu.MenuItem>
))}
</Menu>
</div>
<div className="md:w-10/12 w-full">
<AdaptableCard>
{activeMainGroup?.subGroups.map((subGroup) => (
<Card
key={subGroup.subGroupName}
className="mb-5 "
header={translate('::' + subGroup.subGroupName)}
>
<Formik
initialValues={subGroup.settings.reduce((acc: any, cur) => {
if (!cur.code) {
return acc
}
if (cur.dataType === 'Bool') {
acc[cur.code] = cur.valueBool
} else {
acc[cur.code] = cur.value
}
return acc
}, {})}
onSubmit={(values, { setSubmitting }) => {
setSubmitting(true)
setTimeout(() => {
onFormSubmit(values, setSubmitting, activeMainGroupKey)
}, 1000)
}}
>
{({ values, touched, errors, isSubmitting }) => (
<Form>
<FormContainer>
{subGroup.settings.map((setting) => (
<FormItem
key={setting.code}
label={translate('::' + setting.name) + ' (' + setting.providers?.replaceAll('|', ', ') + ')'}
extra={
<Tooltip title={translate('::' + setting.description)}>
<FaQuestionCircle className="text-lg cursor-pointer ml-1" />
</Tooltip>
}
>
<>
{setting.dataType === 'Text' && (
<Field type="text" name={setting.code} component={Input} />
)}
{setting.dataType === 'Number' && (
<Field type="number" name={setting.code} component={Input} />
)}
{setting.dataType === 'Memo' && (
<Field type="text" name={setting.code} textArea component={Input} />
)}
{setting.dataType === 'Bool' && (
<Field name={setting.code} component={Checkbox}></Field>
)}
{setting.dataType === 'List' && (
<Field name={setting.code}>
{({ field, form }: FieldProps<any>) => (
<Select
field={field}
form={form}
options={getOptions(setting.selectOptions)}
value={getOptions(setting.selectOptions).filter(
(option) => option.value === values[setting.code],
)}
onChange={(option) =>
form.setFieldValue(field.name, option?.value)
}
/>
)}
</Field>
)}
</>
</FormItem>
))}
<FormItem>
<div className="float-right">
<Button
size="sm"
variant="solid"
className="ltr:mr-2 rtl:ml-2"
type="submit"
loading={isSubmitting}
>
{isSubmitting
? translate('::SavingWithThreeDot')
: translate('::Save')}
</Button>
</div>
</FormItem>
</FormContainer>
</Form>
)}
</Formik>
</Card>
))}
</AdaptableCard>
</div>
</div>
</Container>
)
}
export default Settings