proj/Frontend/components/tickets/ticket-comments.tsx
2026-01-21 11:24:53 +01:00

103 lines
3.8 KiB
TypeScript

"use client"
import { useState, useEffect, useCallback } from "react"
import { useAuth } from "@/lib/auth-context"
import { Button } from "@/components/ui/button"
import { Textarea } from "@/components/ui/textarea"
import { Avatar, AvatarFallback } from "@/components/ui/avatar"
import type { Comment } from "@/lib/types"
interface TicketCommentsProps {
ticketId: number
}
export function TicketComments({ ticketId }: TicketCommentsProps) {
const [comments, setComments] = useState<Comment[]>([])
const [newComment, setNewComment] = useState("")
const [loading, setLoading] = useState(false)
const { user, authHeader } = useAuth()
const API_URL = process.env.NEXT_PUBLIC_API_URL + "/api"
const fetchComments = useCallback(async () => {
if (!authHeader) return
try {
const res = await fetch(`${API_URL}/tickets/${ticketId}/comments`, {
headers: { "Authorization": authHeader }
})
if (res.ok) {
const data = await res.json()
setComments(data)
}
} catch (e) {
console.error(e)
}
}, [ticketId, authHeader])
useEffect(() => {
if (authHeader) {
fetchComments()
}
}, [fetchComments, authHeader])
const handlePost = async () => {
if (!authHeader || !newComment.trim()) return
setLoading(true)
try {
const res = await fetch(`${API_URL}/tickets/${ticketId}/comments`, {
method: "POST",
headers: {
"Authorization": authHeader,
"Content-Type": "application/json"
},
body: JSON.stringify({ text: newComment })
})
if (res.ok) {
setNewComment("")
fetchComments()
}
} catch (e) {
console.error(e)
} finally {
setLoading(false)
}
}
return (
<div className="space-y-4">
<h3 className="font-semibold">Comments</h3>
<div className="space-y-4 max-h-[300px] overflow-y-auto pr-2">
{comments.length === 0 && <p className="text-sm text-muted-foreground">No comments yet.</p>}
{comments.map((comment) => (
<div key={comment.id} className="flex gap-3">
<Avatar className="h-8 w-8">
<AvatarFallback>{comment.author.name ? comment.author.name.charAt(0) : '?'}</AvatarFallback>
</Avatar>
<div className="flex-1 space-y-1">
<div className="flex items-center justify-between">
<span className="text-sm font-medium">{comment.author.name}</span>
<span className="text-xs text-muted-foreground">{new Date(comment.createdAt).toLocaleString()}</span>
</div>
<div className="p-2 bg-muted/50 rounded-md">
<p className="text-sm text-foreground/90 whitespace-pre-wrap">{comment.text}</p>
</div>
</div>
</div>
))}
</div>
<div className="space-y-2 pt-2">
<Textarea
placeholder="Write a comment..."
value={newComment}
onChange={(e) => setNewComment(e.target.value)}
className="min-h-[80px]"
/>
<div className="flex justify-end">
<Button onClick={handlePost} disabled={!newComment.trim() || loading}>
Post Comment
</Button>
</div>
</div>
</div>
)
}