207 lines
5.8 KiB
TypeScript
207 lines
5.8 KiB
TypeScript
import { Component, createSignal, createEffect } from 'solid-js'
|
||
import styles from '../styles/Modal.module.css'
|
||
import Button from '../ui/Button'
|
||
import Modal from '../ui/Modal'
|
||
import HTMLEditor from '../ui/HTMLEditor'
|
||
|
||
interface ReactionEditModalProps {
|
||
reaction: {
|
||
id: number
|
||
kind: string
|
||
body: string
|
||
created_at: number
|
||
updated_at?: number
|
||
deleted_at?: number
|
||
reply_to?: number
|
||
created_by: {
|
||
id: number
|
||
name: string
|
||
email: string
|
||
slug: string
|
||
}
|
||
shout: {
|
||
id: number
|
||
title: string
|
||
slug: string
|
||
layout: string
|
||
created_at: number
|
||
published_at?: number
|
||
deleted_at?: number
|
||
}
|
||
stat: {
|
||
comments_count: number
|
||
rating: number
|
||
}
|
||
}
|
||
isOpen: boolean
|
||
onClose: () => void
|
||
onSave: (reaction: { id: number; body?: string; deleted_at?: number }) => Promise<void>
|
||
}
|
||
|
||
/**
|
||
* Модальное окно для редактирования реакции
|
||
*/
|
||
const ReactionEditModal: Component<ReactionEditModalProps> = (props) => {
|
||
const [body, setBody] = createSignal('')
|
||
const [loading, setLoading] = createSignal(false)
|
||
const [error, setError] = createSignal('')
|
||
|
||
// Инициализация данных при изменении реакции
|
||
createEffect(() => {
|
||
if (props.reaction) {
|
||
setBody(props.reaction.body || '')
|
||
setError('')
|
||
}
|
||
})
|
||
|
||
/**
|
||
* Обработка сохранения изменений
|
||
*/
|
||
async function handleSave() {
|
||
try {
|
||
setLoading(true)
|
||
setError('')
|
||
|
||
const updateData: { id: number; body?: string; deleted_at?: number } = {
|
||
id: props.reaction.id,
|
||
body: body(),
|
||
}
|
||
|
||
await props.onSave(updateData)
|
||
} catch (err) {
|
||
setError(err instanceof Error ? err.message : 'Ошибка сохранения')
|
||
} finally {
|
||
setLoading(false)
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Получает название типа реакции на русском
|
||
*/
|
||
const getReactionName = (kind: string): string => {
|
||
switch (kind) {
|
||
case 'LIKE':
|
||
return 'Лайк'
|
||
case 'DISLIKE':
|
||
return 'Дизлайк'
|
||
case 'COMMENT':
|
||
return 'Комментарий'
|
||
case 'QUOTE':
|
||
return 'Цитата'
|
||
case 'AGREE':
|
||
return 'Согласен'
|
||
case 'DISAGREE':
|
||
return 'Не согласен'
|
||
case 'ASK':
|
||
return 'Вопрос'
|
||
case 'PROPOSE':
|
||
return 'Предложение'
|
||
case 'PROOF':
|
||
return 'Доказательство'
|
||
case 'DISPROOF':
|
||
return 'Опровержение'
|
||
case 'ACCEPT':
|
||
return 'Принять'
|
||
case 'REJECT':
|
||
return 'Отклонить'
|
||
case 'CREDIT':
|
||
return 'Упоминание'
|
||
case 'SILENT':
|
||
return 'Причастность'
|
||
default:
|
||
return kind
|
||
}
|
||
}
|
||
|
||
return (
|
||
<Modal isOpen={props.isOpen} onClose={props.onClose} title="Редактирование реакции">
|
||
<div class={styles['modal-content']}>
|
||
{error() && (
|
||
<div class={styles['error-message']}>
|
||
{error()}
|
||
</div>
|
||
)}
|
||
|
||
<div class={styles['form-group']}>
|
||
<label class={styles['form-label']}>ID реакции:</label>
|
||
<input
|
||
type="text"
|
||
value={props.reaction.id}
|
||
disabled
|
||
class={styles['form-input']}
|
||
/>
|
||
</div>
|
||
|
||
<div class={styles['form-group']}>
|
||
<label class={styles['form-label']}>Тип реакции:</label>
|
||
<input
|
||
type="text"
|
||
value={getReactionName(props.reaction.kind)}
|
||
disabled
|
||
class={styles['form-input']}
|
||
/>
|
||
</div>
|
||
|
||
<div class={styles['form-group']}>
|
||
<label class={styles['form-label']}>Автор:</label>
|
||
<input
|
||
type="text"
|
||
value={`${props.reaction.created_by.name || 'Без имени'} (${props.reaction.created_by.email})`}
|
||
disabled
|
||
class={styles['form-input']}
|
||
/>
|
||
</div>
|
||
|
||
<div class={styles['form-group']}>
|
||
<label class={styles['form-label']}>Публикация:</label>
|
||
<input
|
||
type="text"
|
||
value={`${props.reaction.shout.title} (ID: ${props.reaction.shout.id})`}
|
||
disabled
|
||
class={styles['form-input']}
|
||
/>
|
||
</div>
|
||
|
||
<div class={styles['form-group']}>
|
||
<label class={styles['form-label']}>Текст реакции:</label>
|
||
<HTMLEditor
|
||
value={body()}
|
||
onInput={(value) => setBody(value)}
|
||
placeholder="Введите текст реакции (поддерживается HTML)..."
|
||
rows={6}
|
||
/>
|
||
</div>
|
||
|
||
<div class={styles['form-group']}>
|
||
<label class={styles['form-label']}>Статистика:</label>
|
||
<div class={styles['stat-info']}>
|
||
<span>Рейтинг: {props.reaction.stat.rating}</span>
|
||
<span>Комментариев: {props.reaction.stat.comments_count}</span>
|
||
</div>
|
||
</div>
|
||
|
||
<div class={styles['form-group']}>
|
||
<label class={styles['form-label']}>Статус:</label>
|
||
<input
|
||
type="text"
|
||
value={props.reaction.deleted_at ? 'Удалено' : 'Активно'}
|
||
disabled
|
||
class={styles['form-input']}
|
||
/>
|
||
</div>
|
||
|
||
<div class={styles['modal-actions']}>
|
||
<Button variant="secondary" onClick={props.onClose} disabled={loading()}>
|
||
Отмена
|
||
</Button>
|
||
<Button variant="primary" onClick={handleSave} disabled={loading()}>
|
||
{loading() ? 'Сохранение...' : 'Сохранить'}
|
||
</Button>
|
||
</div>
|
||
</div>
|
||
</Modal>
|
||
)
|
||
}
|
||
|
||
export default ReactionEditModal
|