add modal window for save compaint text template
This commit is contained in:
@@ -994,7 +994,7 @@
|
||||
right: 0;
|
||||
background: none;
|
||||
border: none;
|
||||
color: white;
|
||||
color: v.$white;
|
||||
font-size: 32px;
|
||||
cursor: pointer;
|
||||
padding: 8px;
|
||||
@@ -1004,3 +1004,116 @@
|
||||
opacity: 0.8;
|
||||
}
|
||||
}
|
||||
|
||||
.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;
|
||||
} */
|
||||
@@ -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<ViolationFileDetail>(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 (
|
||||
<div className="violation-info-case">
|
||||
|
||||
<div className="note-form">
|
||||
<form action={formAction}>
|
||||
<input type="hidden" name="violationId" value={localViolation.id} />
|
||||
<section
|
||||
className="note-form-section"
|
||||
>
|
||||
<div
|
||||
className="note-form-group"
|
||||
<>
|
||||
<div className="violation-info-case">
|
||||
<div className="note-form">
|
||||
<form action={formAction}>
|
||||
<input type="hidden" name="violationId" value={localViolation.id} />
|
||||
<section
|
||||
className="note-form-section"
|
||||
>
|
||||
<label
|
||||
className="note-case-label"
|
||||
htmlFor="note"
|
||||
<div
|
||||
className="note-form-group"
|
||||
>
|
||||
{t('text-of-the-complaint')}
|
||||
</label>
|
||||
<label
|
||||
className="note-case-label"
|
||||
htmlFor="note"
|
||||
>
|
||||
{t('text-of-the-complaint')}
|
||||
</label>
|
||||
|
||||
<textarea
|
||||
name="note"
|
||||
className="note-textarea"
|
||||
placeholder={`${t('text-area-error-fill-complaint-text')}...`}
|
||||
value={noteText}
|
||||
onChange={(e) => setNoteText(e.target.value)}
|
||||
<textarea
|
||||
name="note"
|
||||
className="note-textarea"
|
||||
placeholder={`${t('text-area-error-fill-complaint-text')}...`}
|
||||
value={noteText}
|
||||
onChange={(e) => setNoteText(e.target.value)}
|
||||
>
|
||||
</textarea>
|
||||
</div>
|
||||
|
||||
{state?.errorMessage?.textArea && (
|
||||
<p
|
||||
className="text-sm text-red-500"
|
||||
>
|
||||
{
|
||||
state?.errorMessage?.textArea.split('&').map((e, index) => {
|
||||
return (
|
||||
<span key={index}>
|
||||
{t(e)}
|
||||
<br />
|
||||
</span>
|
||||
)
|
||||
})
|
||||
}
|
||||
</p>
|
||||
)}
|
||||
</section>
|
||||
|
||||
<div
|
||||
className="button-actions"
|
||||
>
|
||||
<button
|
||||
type="button"
|
||||
className="btn-s btn-primary-small"
|
||||
onClick={openTemplateSaveModal}
|
||||
>
|
||||
</textarea>
|
||||
{t('save-template')}
|
||||
</button>
|
||||
|
||||
<button
|
||||
type="submit"
|
||||
className="btn-s btn-primary-small"
|
||||
disabled={isPending}
|
||||
>
|
||||
{t('submit-violation')}
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div
|
||||
className="samples-wrapper"
|
||||
>
|
||||
<h5>Шаблоны</h5>
|
||||
|
||||
{state?.errorMessage?.textArea && (
|
||||
<p
|
||||
className="text-sm text-red-500"
|
||||
>
|
||||
|
||||
{
|
||||
state?.errorMessage?.textArea.split('&').map((e, index) => {
|
||||
return (
|
||||
<span key={index}>
|
||||
{t(e)}
|
||||
<br />
|
||||
</span>
|
||||
)
|
||||
})
|
||||
}
|
||||
</p>
|
||||
)}
|
||||
</section>
|
||||
|
||||
<div
|
||||
className="button-actions"
|
||||
<ul
|
||||
className="samples-list"
|
||||
>
|
||||
<button
|
||||
type="submit"
|
||||
className="btn-s btn-primary-small"
|
||||
disabled={isPending}
|
||||
<li
|
||||
className="sample-item"
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
templateHandler(e)
|
||||
}}
|
||||
>
|
||||
Сохранить шаблон
|
||||
</button>
|
||||
|
||||
<button
|
||||
type="submit"
|
||||
className="btn-s btn-primary-small"
|
||||
disabled={isPending}
|
||||
<div
|
||||
className="sample-item-title"
|
||||
>
|
||||
title 1
|
||||
</div>
|
||||
<div
|
||||
className="sample-item-text"
|
||||
>
|
||||
1text text text text text text text text text text text text
|
||||
</div>
|
||||
</li>
|
||||
<li
|
||||
className="sample-item"
|
||||
onClick={(e) => {
|
||||
templateHandler(e)
|
||||
}}
|
||||
>
|
||||
{t('submit-violation')}
|
||||
<div
|
||||
className="sample-item-title"
|
||||
>
|
||||
title 2
|
||||
</div>
|
||||
<div
|
||||
className="sample-item-text"
|
||||
>
|
||||
2text text text text text text text text text text text text
|
||||
</div>
|
||||
</li>
|
||||
<li
|
||||
className="sample-item"
|
||||
onClick={(e) => {
|
||||
templateHandler(e)
|
||||
}}
|
||||
>
|
||||
<div
|
||||
className="sample-item-title"
|
||||
>
|
||||
title 3
|
||||
</div>
|
||||
<div
|
||||
className="sample-item-text"
|
||||
>
|
||||
3text text text text text text text text text text text text
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<li
|
||||
className="sample-item"
|
||||
onClick={(e) => {
|
||||
templateHandler(e)
|
||||
}}
|
||||
>
|
||||
<div
|
||||
className="sample-item-title"
|
||||
>
|
||||
title 3
|
||||
</div>
|
||||
<div
|
||||
className="sample-item-text"
|
||||
>
|
||||
3text text text text text text text text text text text text
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<li
|
||||
className="sample-item"
|
||||
onClick={(e) => {
|
||||
templateHandler(e)
|
||||
}}
|
||||
>
|
||||
<div
|
||||
className="sample-item-title"
|
||||
>
|
||||
title 3
|
||||
</div>
|
||||
<div
|
||||
className="sample-item-text"
|
||||
>
|
||||
3text text text text text text text text text text text text
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<ModalWindow
|
||||
state={isTemplateModalOpen}
|
||||
callBack={setIsTemplateModalOpen}
|
||||
>
|
||||
<div className="template-modal-content">
|
||||
<div className="template-modal-header">
|
||||
<h3>{t('save-template')}</h3>
|
||||
<button
|
||||
className="template-modal-close"
|
||||
onClick={() => setIsTemplateModalOpen(false)}
|
||||
>
|
||||
×
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
<div className="template-modal-body">
|
||||
<div className="template-form-group">
|
||||
<label htmlFor="templateName">
|
||||
{t('template-name')}:
|
||||
</label>
|
||||
<input
|
||||
id="templateName"
|
||||
type="text"
|
||||
className="template-name-input"
|
||||
placeholder={t('enter-template-name')}
|
||||
value={templateName}
|
||||
onChange={(e) => setTemplateName(e.target.value)}
|
||||
autoFocus
|
||||
/>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div
|
||||
className="samples-wrapper"
|
||||
>
|
||||
<h5>Шаблоны</h5>
|
||||
|
||||
<ul
|
||||
className="samples-list"
|
||||
>
|
||||
<li
|
||||
className="sample-item"
|
||||
onClick={(e) => {
|
||||
templateHandler(e)
|
||||
}}
|
||||
>
|
||||
<div
|
||||
className="sample-item-title"
|
||||
>
|
||||
title 1
|
||||
<div className="template-preview">
|
||||
<div className="template-preview-label">
|
||||
{t('complaint-text-preview')}
|
||||
</div>
|
||||
<div className="template-preview-text">
|
||||
{noteText || t('no-text')}
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className="sample-item-text"
|
||||
</div>
|
||||
<div className="template-modal-footer">
|
||||
<button
|
||||
className="btn-s btn-primary-small"
|
||||
onClick={() => setIsTemplateModalOpen(false)}
|
||||
>
|
||||
1text text text text text text text text text text text text
|
||||
</div>
|
||||
</li>
|
||||
<li
|
||||
className="sample-item"
|
||||
onClick={(e) => {
|
||||
templateHandler(e)
|
||||
}}
|
||||
>
|
||||
<div
|
||||
className="sample-item-title"
|
||||
{t('cancel')}
|
||||
</button>
|
||||
<button
|
||||
className="btn-s btn-resolve"
|
||||
onClick={saveTemplateHandler}
|
||||
>
|
||||
title 2
|
||||
</div>
|
||||
<div
|
||||
className="sample-item-text"
|
||||
>
|
||||
2text text text text text text text text text text text text
|
||||
</div>
|
||||
</li>
|
||||
<li
|
||||
className="sample-item"
|
||||
onClick={(e) => {
|
||||
templateHandler(e)
|
||||
}}
|
||||
>
|
||||
<div
|
||||
className="sample-item-title"
|
||||
>
|
||||
title 3
|
||||
</div>
|
||||
<div
|
||||
className="sample-item-text"
|
||||
>
|
||||
3text text text text text text text text text text text text
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<li
|
||||
className="sample-item"
|
||||
onClick={(e) => {
|
||||
templateHandler(e)
|
||||
}}
|
||||
>
|
||||
<div
|
||||
className="sample-item-title"
|
||||
>
|
||||
title 3
|
||||
</div>
|
||||
<div
|
||||
className="sample-item-text"
|
||||
>
|
||||
3text text text text text text text text text text text text
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<li
|
||||
className="sample-item"
|
||||
onClick={(e) => {
|
||||
templateHandler(e)
|
||||
}}
|
||||
>
|
||||
<div
|
||||
className="sample-item-title"
|
||||
>
|
||||
title 3
|
||||
</div>
|
||||
<div
|
||||
className="sample-item-text"
|
||||
>
|
||||
3text text text text text text text text text text text text
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
{t('save')}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</ModalWindow>
|
||||
</>
|
||||
);
|
||||
} else {
|
||||
if (isLoadingComplain) {
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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": "и",
|
||||
|
||||
Reference in New Issue
Block a user