SendMessageModal.tsx 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. import { useEffect, useState } from 'react'
  2. import { Input, Modal } from 'ui'
  3. import { FormItemLayout } from 'ui-patterns/form/FormItemLayout/FormItemLayout'
  4. import CodeEditor from '@/components/ui/CodeEditor/CodeEditor'
  5. import { tryParseJson } from '@/lib/helpers'
  6. interface SendMessageModalProps {
  7. visible: boolean
  8. onSelectCancel: () => void
  9. onSelectConfirm: (v: { message: string; payload: string }) => void
  10. }
  11. const defaultPayload = {
  12. message: 'Test message',
  13. payload: '{ "message": "Hello World" }',
  14. }
  15. export const SendMessageModal = ({
  16. visible,
  17. onSelectCancel,
  18. onSelectConfirm,
  19. }: SendMessageModalProps) => {
  20. const [error, setError] = useState<string>()
  21. const [values, setValues] = useState(defaultPayload)
  22. useEffect(() => {
  23. if (visible) {
  24. setError(undefined)
  25. setValues(defaultPayload)
  26. }
  27. }, [visible])
  28. return (
  29. <Modal
  30. size="medium"
  31. alignFooter="right"
  32. header="Broadcast a message to all clients"
  33. visible={visible}
  34. loading={false}
  35. onCancel={onSelectCancel}
  36. onConfirm={() => {
  37. const payload = tryParseJson(values.payload)
  38. if (payload === undefined) {
  39. setError('Please provide a valid JSON')
  40. } else {
  41. onSelectConfirm({ ...values, payload })
  42. }
  43. }}
  44. >
  45. <Modal.Content className="flex flex-col gap-y-4">
  46. <FormItemLayout label="Message name" layout="vertical" isReactForm={false}>
  47. <Input
  48. size="small"
  49. value={values.message}
  50. onChange={(v) => setValues({ ...values, message: v.target.value })}
  51. />
  52. </FormItemLayout>
  53. <div className="flex flex-col gap-y-2">
  54. <FormItemLayout label="Message payload" layout="vertical" isReactForm={false}>
  55. <CodeEditor
  56. id="message-payload"
  57. language="json"
  58. className="mb-0! h-32 overflow-hidden rounded-sm border"
  59. onInputChange={(e: string | undefined) =>
  60. setValues({ ...values, payload: e ?? '{}' })
  61. }
  62. options={{ wordWrap: 'off', contextmenu: false }}
  63. value={values.payload}
  64. />
  65. {error !== undefined && <p className="text-sm text-red-900">{error}</p>}
  66. </FormItemLayout>
  67. </div>
  68. </Modal.Content>
  69. </Modal>
  70. )
  71. }