// routes/tenant/messages/[id]/index.tsx import { define } from "../../../../utils.ts"; import { page } from "fresh"; import { getMessageThread, markThreadAsRead, } from "../../../../services/messageService.ts"; import { Message } from "../../../../db/interfaces.ts"; import { AlertMessage } from "../../maintenance/new/components/AlertMessage.tsx"; interface MessageThreadPageData { thread: Message[]; error?: string; currentUserId: string; rootMessageId: string; } export const handler = define.handlers({ async GET(ctx) { const { user_id } = ctx.state.data; const messageId = ctx.params.id; try { const thread = await getMessageThread(messageId); if (!thread || thread.length === 0) { return page({ thread: [], error: "Message thread not found.", currentUserId: user_id, rootMessageId: messageId, }); } const rootMessageId = thread[0].parent_message_id || thread[0].id; await markThreadAsRead(user_id, rootMessageId); return page({ thread, currentUserId: user_id, rootMessageId, }); } catch (error) { console.error("Error loading message thread:", error); return page({ thread: [], error: "Failed to load message thread.", currentUserId: user_id, rootMessageId: messageId, }); } }, }); // Helper component for rendering a single message function MessageBubble( { message, isOutgoing }: { message: Message; isOutgoing: boolean }, ) { const bubbleClass = isOutgoing ? "bg-blue-500 text-white self-end rounded-br-none" : "bg-gray-200 text-gray-800 self-start rounded-tl-none"; const alignmentClass = isOutgoing ? "justify-end" : "justify-start"; const date = message.created_on ? new Date(message.created_on).toLocaleString() : "Unknown Date"; const attachments = Array.isArray(message.attachments_json) ? message.attachments_json : message.attachments_json ? JSON.parse(message.attachments_json as unknown as string) : []; const content = message.content_encrypted || message.content || ""; return (

{isOutgoing ? "You" : "Landlord"} - {date}

{content}

{attachments.length > 0 && (

Attachments:

    {attachments.map((att: { url: string; name: string }) => (
  • {att.name}
  • ))}
)}
); } export default define.page(function MessageThreadPage({ data }) { const { thread, error, currentUserId, rootMessageId } = data as MessageThreadPageData; const rootMessage = thread[0]; const subject = rootMessage?.subject || "Conversation"; return (
{/* Header */}

Message Thread

Subject: {subject}

{/* Main Content */}
{error && {error}}
{thread.map((message) => ( ))}
{/* Reply Button at the bottom for convenience */}
); });