mirror of
https://git.coastit.co.za/caitlin/CRM_ENVR.git
synced 2026-07-10 11:15:43 +02:00
132 lines
4.5 KiB
TypeScript
132 lines
4.5 KiB
TypeScript
import { NextRequest, NextResponse } from "next/server"
|
|
import { getSessionUser } from "@/lib/auth"
|
|
import { query } from "@/lib/db"
|
|
import { avatarSvgUrl } from "@/lib/avatar"
|
|
|
|
export async function GET() {
|
|
try {
|
|
const user = await getSessionUser()
|
|
if (!user) return NextResponse.json({ error: "Unauthorized" }, { status: 401 })
|
|
|
|
const result = await query(
|
|
`SELECT
|
|
c.id,
|
|
c.updated_at,
|
|
cp_me.last_read_at,
|
|
u.id AS other_user_id,
|
|
u.first_name || ' ' || u.last_name AS other_user_name,
|
|
u.email AS other_user_email,
|
|
u.avatar_url AS other_user_avatar_url,
|
|
(SELECT content FROM messages WHERE conversation_id = c.id ORDER BY created_at DESC LIMIT 1) AS last_message,
|
|
(SELECT created_at FROM messages WHERE conversation_id = c.id ORDER BY created_at DESC LIMIT 1) AS last_message_time,
|
|
(SELECT count(*) FROM messages WHERE conversation_id = c.id AND sender_id != $1 AND created_at > COALESCE(cp_me.last_read_at, '1970-01-01')) AS unread
|
|
FROM conversations c
|
|
JOIN conversation_participants cp_me ON cp_me.conversation_id = c.id AND cp_me.user_id = $1
|
|
JOIN conversation_participants cp ON cp.conversation_id = c.id
|
|
JOIN users u ON u.id = cp.user_id AND u.id != $1
|
|
WHERE c.id IN (
|
|
SELECT conversation_id FROM conversation_participants WHERE user_id = $1
|
|
)
|
|
ORDER BY c.updated_at DESC
|
|
LIMIT 50`,
|
|
[user.id],
|
|
)
|
|
|
|
const conversations = result.rows.map((row: any) => ({
|
|
id: row.id,
|
|
updatedAt: row.updated_at,
|
|
otherUser: {
|
|
id: row.other_user_id,
|
|
name: row.other_user_name,
|
|
email: row.other_user_email,
|
|
avatar: avatarSvgUrl(row.other_user_name),
|
|
},
|
|
lastMessage: row.last_message || "",
|
|
lastMessageTime: row.last_message_time ? timeAgo(new Date(row.last_message_time)) : "",
|
|
unread: parseInt(row.unread) || 0,
|
|
}))
|
|
|
|
return NextResponse.json({ conversations })
|
|
} catch (error) {
|
|
console.error("Conversations error:", error)
|
|
return NextResponse.json({ error: "Failed to load conversations" }, { status: 500 })
|
|
}
|
|
}
|
|
|
|
export async function POST(request: NextRequest) {
|
|
try {
|
|
const user = await getSessionUser()
|
|
if (!user) return NextResponse.json({ error: "Unauthorized" }, { status: 401 })
|
|
|
|
const { userId } = await request.json()
|
|
if (!userId) {
|
|
return NextResponse.json({ error: "userId is required" }, { status: 400 })
|
|
}
|
|
|
|
if (userId === user.id) {
|
|
return NextResponse.json({ error: "Cannot start a conversation with yourself" }, { status: 400 })
|
|
}
|
|
|
|
const existing = await query(
|
|
`SELECT c.id FROM conversations c
|
|
JOIN conversation_participants cp1 ON cp1.conversation_id = c.id AND cp1.user_id = $1
|
|
JOIN conversation_participants cp2 ON cp2.conversation_id = c.id AND cp2.user_id = $2
|
|
LIMIT 1`,
|
|
[user.id, userId],
|
|
)
|
|
|
|
if (existing.rows.length > 0) {
|
|
return NextResponse.json({ conversationId: existing.rows[0].id })
|
|
}
|
|
|
|
const convResult = await query(
|
|
`INSERT INTO conversations DEFAULT VALUES RETURNING id`,
|
|
)
|
|
const conversationId = convResult.rows[0].id
|
|
|
|
await query(
|
|
`INSERT INTO conversation_participants (conversation_id, user_id, last_read_at) VALUES ($1, $2, NOW()), ($1, $3, NOW())`,
|
|
[conversationId, user.id, userId],
|
|
)
|
|
|
|
const otherUser = await query(
|
|
`SELECT id, first_name || ' ' || last_name AS name, email, avatar_url
|
|
FROM users WHERE id = $1`,
|
|
[userId],
|
|
)
|
|
|
|
const other = otherUser.rows[0]
|
|
|
|
return NextResponse.json({
|
|
conversation: {
|
|
id: conversationId,
|
|
updatedAt: new Date().toISOString(),
|
|
otherUser: {
|
|
id: other.id,
|
|
name: other.name,
|
|
email: other.email,
|
|
avatar: avatarSvgUrl(other.name),
|
|
},
|
|
lastMessage: "",
|
|
lastMessageTime: "",
|
|
unread: 0,
|
|
},
|
|
})
|
|
} catch (error) {
|
|
console.error("Create conversation error:", error)
|
|
return NextResponse.json({ error: "Failed to create conversation" }, { status: 500 })
|
|
}
|
|
}
|
|
|
|
function timeAgo(date: Date): string {
|
|
const seconds = Math.floor((Date.now() - date.getTime()) / 1000)
|
|
if (seconds < 60) return "now"
|
|
const minutes = Math.floor(seconds / 60)
|
|
if (minutes < 60) return `${minutes}m ago`
|
|
const hours = Math.floor(minutes / 60)
|
|
if (hours < 24) return `${hours}h ago`
|
|
const days = Math.floor(hours / 24)
|
|
if (days < 7) return `${days}d ago`
|
|
return date.toLocaleDateString()
|
|
}
|