From 4e8289e9766e768706a121dd057458a0e001a7a8 Mon Sep 17 00:00:00 2001 From: smanylov Date: Wed, 29 Apr 2026 17:09:05 +0700 Subject: [PATCH] add modal window for save compaint text template --- src/app/styles/violation-details.scss | 117 +++++- .../violation-table/case-complaint.tsx | 387 +++++++++++------- src/i18n/messages/en.json | 11 +- src/i18n/messages/ru.json | 11 +- 4 files changed, 369 insertions(+), 157 deletions(-) diff --git a/src/app/styles/violation-details.scss b/src/app/styles/violation-details.scss index df21548..0df47bd 100644 --- a/src/app/styles/violation-details.scss +++ b/src/app/styles/violation-details.scss @@ -994,7 +994,7 @@ right: 0; background: none; border: none; - color: white; + color: v.$white; font-size: 32px; cursor: pointer; padding: 8px; @@ -1003,4 +1003,117 @@ &:hover { opacity: 0.8; } -} \ No newline at end of file +} + +.template-modal-content { + min-width: 400px; + max-width: 500px; + background: v.$white; + border-radius: 8px; + overflow: hidden; +} + +.template-modal-header { + display: flex; + justify-content: space-between; + align-items: center; + padding: 16px 20px; + border-bottom: 1px solid v.$border-color-1; +} + +.template-modal-header h3 { + margin: 0; + font-size: 18px; + font-weight: 600; +} + +.template-modal-close { + background: none; + border: none; + font-size: 24px; + cursor: pointer; + color: #666; + padding: 0; + width: 30px; + height: 30px; + display: flex; + align-items: center; + justify-content: center; + border-radius: 4px; + transition: all 0.2s; +} + +.template-modal-close:hover { + background: v.$border-color-1; + color: v.$text-p; +} + +.template-modal-body { + padding: 20px; +} + +.template-form-group { + margin-bottom: 20px; +} + +.template-form-group label { + display: block; + margin-bottom: 8px; + font-weight: 500; + color: v.$text-p; +} + +.template-name-input { + width: 100%; + padding: 8px 12px; + border: 1px solid #ddd; + border-radius: 8px; + font-size: 14px; + transition: border-color 0.2s; +} + +.template-name-input:focus { + outline: none; + box-shadow: 0 0 0 2px rgba(74, 144, 226, 0.1); +} + +.template-preview { + margin-top: 20px; +} + +.template-preview-label { + font-weight: 500; + margin-bottom: 8px; + color: v.$text-p; +} + +.template-preview-text { + background: v.$bg-hover; + padding: 12px; + border-radius: 8px; + max-height: 200px; + overflow-y: auto; + font-size: 14px; + line-height: 1.5; + white-space: pre-wrap; + word-wrap: break-word; + color: v.$text-s; +} + +.template-modal-footer { + display: flex; + justify-content: flex-end; + gap: 12px; + padding: 16px 20px; + border-top: 1px solid v.$border-color-1; +} + +/* .btn-secondary { + background: #6c757d; + color: v.$white; + border: none; +} + +.btn-secondary:hover { + background: #5a6268; +} */ \ No newline at end of file diff --git a/src/app/ui/file-page/violation-table/case-complaint.tsx b/src/app/ui/file-page/violation-table/case-complaint.tsx index 9325420..b87eab0 100644 --- a/src/app/ui/file-page/violation-table/case-complaint.tsx +++ b/src/app/ui/file-page/violation-table/case-complaint.tsx @@ -7,6 +7,7 @@ import { createComplaint, fetchComplainInfo, MatchStatus } from '@/app/actions/v import { toast } from 'sonner'; import { useQuery } from '@tanstack/react-query'; import { formatDate, formatDateTime } from '@/app/lib/formatDate'; +import ModalWindow from '@/app/components/ModalWindow'; interface complaintInfo { id: number, @@ -28,6 +29,8 @@ export default function CaseComplaint({ selectedViolation, updateStatusHandler } const [localViolation, setLocalViolation] = useState(selectedViolation); const [noteText, setNoteText] = useState(''); const [state, formAction, isPending] = useActionState(createComplaint, undefined); + const [isTemplateModalOpen, setIsTemplateModalOpen] = useState(false); + const [templateName, setTemplateName] = useState(''); useEffect(() => { setLocalViolation(selectedViolation); @@ -77,178 +80,256 @@ export default function CaseComplaint({ selectedViolation, updateStatusHandler } } } + function openTemplateSaveModal() { + if (!noteText.trim()) { + toast.warning(t('please-enter-complaint-text-first')); + return; + } + setTemplateName(''); + setIsTemplateModalOpen(true); + } + + function saveTemplateHandler() { + if (!templateName.trim()) { + toast.warning(t('please-enter-template-name')); + return; + } + + // пока нету эндпоинта оставлю заглушку + console.log('СОХРАНЕНИЕ ШАБЛОНА'); + console.log('Название шаблона:', templateName); + console.log('Текст жалобы:', noteText); + console.log('========================'); + + toast.success(t('template-saved-successfully') || 'Шаблон успешно сохранен'); + setIsTemplateModalOpen(false); + setTemplateName(''); + } + if (!ENABLED_STATUSES.includes(localViolation.status)) { return ( -
- -
-
- -
-
+
+
+ + +
- + - +
+ + {state?.errorMessage?.textArea && ( +

+ { + state?.errorMessage?.textArea.split('&').map((e, index) => { + return ( + + {t(e)} +
+
+ ) + }) + } +

+ )} +
+ +
+ + +
+
+
+
+
Шаблоны
- {state?.errorMessage?.textArea && ( -

- - { - state?.errorMessage?.textArea.split('&').map((e, index) => { - return ( - - {t(e)} -
-
- ) - }) - } -

- )} - - -
- - -
+
+ 1text text text text text text text text text text text text +
+ +
  • { + templateHandler(e) + }} > - {t('submit-violation')} +
    + title 2 +
    +
    + 2text text text text text text text text text text text text +
    +
  • +
  • { + templateHandler(e) + }} + > +
    + title 3 +
    +
    + 3text text text text text text text text text text text text +
    +
  • + +
  • { + templateHandler(e) + }} + > +
    + title 3 +
    +
    + 3text text text text text text text text text text text text +
    +
  • + +
  • { + templateHandler(e) + }} + > +
    + title 3 +
    +
    + 3text text text text text text text text text text text text +
    +
  • + +
    +
    + + +
    +
    +

    {t('save-template')}

    +
    - +
    +
    + + setTemplateName(e.target.value)} + autoFocus + /> +
    -
    -
    -
    Шаблоны
    - -
      -
    • { - templateHandler(e) - }} - > -
      - title 1 +
      +
      + {t('complaint-text-preview')} +
      +
      + {noteText || t('no-text')} +
      -
      +
      +
      -
    • -
    • { - templateHandler(e) - }} - > -
      +
      -
      - 2text text text text text text text text text text text text -
      -
    • -
    • { - templateHandler(e) - }} - > -
      - title 3 -
      -
      - 3text text text text text text text text text text text text -
      -
    • - -
    • { - templateHandler(e) - }} - > -
      - title 3 -
      -
      - 3text text text text text text text text text text text text -
      -
    • - -
    • { - templateHandler(e) - }} - > -
      - title 3 -
      -
      - 3text text text text text text text text text text text text -
      -
    • -
    -
    -
    + {t('save')} + + + +
    + ); } else { if (isLoadingComplain) { diff --git a/src/i18n/messages/en.json b/src/i18n/messages/en.json index 77be32b..a0ec0f6 100644 --- a/src/i18n/messages/en.json +++ b/src/i18n/messages/en.json @@ -454,7 +454,16 @@ "select-at-least-one-filter": "Select at least one filter", "select-document-to-upload": "Select document(s) to upload", "uploading-id-images": "Uploading ID images", - "tracking": "Tracking" + "tracking": "Tracking", + "save-template": "Save template", + "save": "Save", + "template-name": "Template name", + "enter-template-name": "Enter template name", + "complaint-text-preview": "Complaint text preview", + "no-text": "No text", + "please-enter-complaint-text-first": "Please enter complaint text first", + "please-enter-template-name": "Please enter template name", + "template-saved-successfully": "Template saved successfully" }, "Login-register-form": { "and": "and", diff --git a/src/i18n/messages/ru.json b/src/i18n/messages/ru.json index fcbf3ef..b7efe2a 100644 --- a/src/i18n/messages/ru.json +++ b/src/i18n/messages/ru.json @@ -454,7 +454,16 @@ "select-at-least-one-filter": "Выберите хотя бы один фильтр", "select-document-to-upload": "Выберите документ(ы) для загрузки", "uploading-id-images": "Загрузка изображений удостоверения личности", - "tracking": "Отслеживание" + "tracking": "Отслеживание", + "save-template": "Сохранить шаблон", + "save": "Сохранить", + "template-name": "Название шаблона", + "enter-template-name": "Введите название шаблона", + "complaint-text-preview": "Предварительный просмотр текста жалобы", + "no-text": "Нет текста", + "please-enter-complaint-text-first": "Пожалуйста, сначала введите текст жалобы", + "please-enter-template-name": "Пожалуйста, введите название шаблона", + "template-saved-successfully": "Шаблон успешно сохранен" }, "Login-register-form": { "and": "и",