diff --git a/app/src/components/ComplaintCard.tsx b/app/src/components/ComplaintCard.tsx index ed2ac8e..477d98a 100644 --- a/app/src/components/ComplaintCard.tsx +++ b/app/src/components/ComplaintCard.tsx @@ -3,6 +3,7 @@ import { createPortal } from 'react-dom'; import { Zap, Hammer, Trash2, Pencil, X, Check, Calendar, MapPin, BedDouble, MessageSquare, Wrench, GitBranch, ChevronRight, UserCircle, Clock, + Send, AlertCircle, } from 'lucide-react'; import { POST_PLACES } from '../constants/models'; @@ -10,17 +11,11 @@ import { POST_PLACES } from '../constants/models'; export type Role = 'faculty' | 'warden' | 'centrehead'; -export interface CommentAuthor { - id: number; - email: string; - position: string; -} - export interface ComplaintComment { id: number; comment_text: string; - author_id: number; - Author?: CommentAuthor; + email: string; + role: string; created_at: string; } @@ -57,6 +52,9 @@ interface ComplaintCardProps { onCancelEdit: () => void; onSaveEdit: (postId: number) => void; onDelete: (postId: number) => void; + // Called after the author successfully posts a comment, so the parent can + // refetch and surface the new comment. + onCommentPosted?: () => void; } // ── Status config ────────────────────────────────────────────────────────────── @@ -195,7 +193,7 @@ function CommentsList({ comments }: { comments: ComplaintComment[] }) { return (
{comments.map((c, idx) => { - const author = c.Author?.position ? roleLabel(c.Author.position) : `Admin #${c.author_id}`; + const author = c.role ? roleLabel(c.role) : 'Staff'; const initials = author.split(' ').map((w) => w[0]).slice(0, 2).join('').toUpperCase(); return (
@@ -208,7 +206,10 @@ function CommentsList({ comments }: { comments: ComplaintComment[] }) {
- {author} + + {author} + {c.email && {c.email}} + {formatDateTime(c.created_at)} @@ -225,6 +226,74 @@ function CommentsList({ comments }: { comments: ComplaintComment[] }) { ); } +// ── Comment composer (post author only) ────────────────────────────────────────── + +function CommentComposer({ role, postId, onPosted }: { role: Role; postId: number; onPosted?: () => void }) { + const [text, setText] = useState(''); + const [submitting, setBusy] = useState(false); + const [error, setError] = useState(null); + + const disabled = submitting || !text.trim(); + + async function submit() { + const content = text.trim(); + if (!content) return; + setBusy(true); + setError(null); + try { + const res = await fetch(`/api/post/${role}/comment/${postId}`, { + method: 'POST', + credentials: 'include', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ Content: content }), + }); + if (!res.ok) { + let msg = `Failed to post comment (${res.status})`; + try { const b = await res.json(); if (b?.error) msg = b.error; } catch {} + throw new Error(msg); + } + setText(''); + onPosted?.(); + } catch (err) { + setError((err as Error).message); + } finally { + setBusy(false); + } + } + + return ( +
+
+