moderation-content.tsx 2.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. import type { FC } from 'react'
  2. import { memo } from 'react'
  3. import { useTranslation } from 'react-i18next'
  4. import Switch from '@/app/components/base/switch'
  5. import type { ModerationContentConfig } from '@/models/debug'
  6. type ModerationContentProps = {
  7. title: string
  8. info?: string
  9. showPreset?: boolean
  10. config: ModerationContentConfig
  11. onConfigChange: (config: ModerationContentConfig) => void
  12. }
  13. const ModerationContent: FC<ModerationContentProps> = ({
  14. title,
  15. info,
  16. showPreset = true,
  17. config,
  18. onConfigChange,
  19. }) => {
  20. const { t } = useTranslation()
  21. const handleConfigChange = (field: string, value: boolean | string) => {
  22. if (field === 'preset_response' && typeof value === 'string')
  23. value = value.slice(0, 100)
  24. onConfigChange({ ...config, [field]: value })
  25. }
  26. return (
  27. <div className='py-2'>
  28. <div className='rounded-lg bg-gray-50 border border-gray-200'>
  29. <div className='flex items-center justify-between px-3 h-10 rounded-lg'>
  30. <div className='shrink-0 text-sm font-medium text-gray-900'>{title}</div>
  31. <div className='grow flex items-center justify-end'>
  32. {
  33. info && (
  34. <div className='mr-2 text-xs text-gray-500 truncate' title={info}>{info}</div>
  35. )
  36. }
  37. <Switch
  38. size='l'
  39. defaultValue={config.enabled}
  40. onChange={v => handleConfigChange('enabled', v)}
  41. />
  42. </div>
  43. </div>
  44. {
  45. config.enabled && showPreset && (
  46. <div className='px-3 pt-1 pb-3 bg-white rounded-lg'>
  47. <div className='flex items-center justify-between h-8 text-[13px] font-medium text-gray-700'>
  48. {t('appDebug.feature.moderation.modal.content.preset')}
  49. <span className='text-xs font-normal text-gray-500'>{t('appDebug.feature.moderation.modal.content.supportMarkdown')}</span>
  50. </div>
  51. <div className='relative px-3 py-2 h-20 rounded-lg bg-gray-100'>
  52. <textarea
  53. value={config.preset_response || ''}
  54. className='block w-full h-full bg-transparent text-sm outline-none appearance-none resize-none'
  55. placeholder={t('appDebug.feature.moderation.modal.content.placeholder') || ''}
  56. onChange={e => handleConfigChange('preset_response', e.target.value)}
  57. />
  58. <div className='absolute bottom-2 right-2 flex items-center px-1 h-5 rounded-md bg-gray-50 text-xs font-medium text-gray-300'>
  59. <span>{(config.preset_response || '').length}</span>/<span className='text-gray-500'>100</span>
  60. </div>
  61. </div>
  62. </div>
  63. )
  64. }
  65. </div>
  66. </div>
  67. )
  68. }
  69. export default memo(ModerationContent)