fix: comments newest-first, input on top
All checks were successful
Deploy Web Client / deploy (push) Successful in 35s

This commit is contained in:
Markov 2026-02-23 13:18:20 +01:00
parent 51844e61ca
commit 1aa0d3923f

View File

@ -1,6 +1,6 @@
"use client"; "use client";
import { useEffect, useRef, useState } from "react"; import { useEffect, useState } from "react";
import { import {
Task, Member, Step, Message, Task, Member, Step, Message,
updateTask, deleteTask, getMembers, updateTask, deleteTask, getMembers,
@ -53,7 +53,6 @@ export default function TaskModal({ task, projectId, projectSlug, onClose, onUpd
const [confirmDelete, setConfirmDelete] = useState(false); const [confirmDelete, setConfirmDelete] = useState(false);
const [newStep, setNewStep] = useState(""); const [newStep, setNewStep] = useState("");
const [newComment, setNewComment] = useState(""); const [newComment, setNewComment] = useState("");
const commentsEndRef = useRef<HTMLDivElement>(null);
useEffect(() => { useEffect(() => {
getMembers().then(setMembers).catch(() => {}); getMembers().then(setMembers).catch(() => {});
@ -61,10 +60,6 @@ export default function TaskModal({ task, projectId, projectSlug, onClose, onUpd
getMessages({ task_id: task.id }).then(setComments).catch(() => {}); getMessages({ task_id: task.id }).then(setComments).catch(() => {});
}, [task.id]); }, [task.id]);
useEffect(() => {
commentsEndRef.current?.scrollIntoView({ behavior: "smooth" });
}, [comments]);
const save = async (patch: Partial<Task>) => { const save = async (patch: Partial<Task>) => {
setSaving(true); setSaving(true);
try { try {
@ -242,8 +237,18 @@ export default function TaskModal({ task, projectId, projectSlug, onClose, onUpd
{/* Comments */} {/* Comments */}
<div> <div>
<div className="text-sm text-[var(--muted)] mb-2">Комментарии</div> <div className="text-sm text-[var(--muted)] mb-2">Комментарии</div>
<div className="flex gap-2 mb-3">
<input
value={newComment}
onChange={(e) => setNewComment(e.target.value)}
onKeyDown={(e) => e.key === "Enter" && handleAddComment()}
placeholder="Написать комментарий..."
className="flex-1 bg-[var(--bg)] border border-[var(--border)] rounded px-2 py-1.5 text-sm outline-none focus:border-[var(--accent)]"
/>
<button onClick={handleAddComment} className="text-xs text-[var(--accent)] px-2"></button>
</div>
<div className="space-y-3 max-h-[300px] overflow-y-auto"> <div className="space-y-3 max-h-[300px] overflow-y-auto">
{comments.map((msg) => ( {[...comments].reverse().map((msg) => (
<div key={msg.id} className="text-sm"> <div key={msg.id} className="text-sm">
<div className="flex items-center gap-1 text-xs text-[var(--muted)] mb-0.5"> <div className="flex items-center gap-1 text-xs text-[var(--muted)] mb-0.5">
<span>{AUTHOR_ICON[msg.author_type] || "👤"}</span> <span>{AUTHOR_ICON[msg.author_type] || "👤"}</span>
@ -257,17 +262,6 @@ export default function TaskModal({ task, projectId, projectSlug, onClose, onUpd
{comments.length === 0 && ( {comments.length === 0 && (
<div className="text-sm text-[var(--muted)] italic">Нет комментариев</div> <div className="text-sm text-[var(--muted)] italic">Нет комментариев</div>
)} )}
<div ref={commentsEndRef} />
</div>
<div className="flex gap-2 mt-3">
<input
value={newComment}
onChange={(e) => setNewComment(e.target.value)}
onKeyDown={(e) => e.key === "Enter" && handleAddComment()}
placeholder="Написать комментарий..."
className="flex-1 bg-[var(--bg)] border border-[var(--border)] rounded px-2 py-1.5 text-sm outline-none focus:border-[var(--accent)]"
/>
<button onClick={handleAddComment} className="text-xs text-[var(--accent)] px-2"></button>
</div> </div>
</div> </div>
</div> </div>