mentor.getRecentMessages: last N unread messages from teams across all of a mentor's assignments. Drives a Recent Messages card on /mentor. applicant.getMentorConversationPreview: last 3 messages + unread count for a given project. Drives a 'Conversation with [Mentor]' card on /applicant — auto-hides when no mentor is assigned. Both procedures use the existing MentorMessage(projectId, createdAt) composite index — no new index needed. Plan: docs/superpowers/plans/2026-04-28-pr6-multi-role-and-workspace-previews.md
67 lines
2.4 KiB
TypeScript
67 lines
2.4 KiB
TypeScript
'use client'
|
|
|
|
import Link from 'next/link'
|
|
import { trpc } from '@/lib/trpc/client'
|
|
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'
|
|
import { Skeleton } from '@/components/ui/skeleton'
|
|
import { MessageCircle } from 'lucide-react'
|
|
|
|
function formatRelativePast(date: Date | string | null): string {
|
|
if (!date) return ''
|
|
const d = typeof date === 'string' ? new Date(date) : date
|
|
const ms = Date.now() - d.getTime()
|
|
const minutes = Math.floor(ms / 60_000)
|
|
const hours = Math.floor(ms / 3_600_000)
|
|
const days = Math.floor(ms / 86_400_000)
|
|
if (days > 0) return `${days}d ago`
|
|
if (hours > 0) return `${hours}h ago`
|
|
return `${Math.max(0, minutes)}m ago`
|
|
}
|
|
|
|
export function RecentMessagesCard() {
|
|
const { data, isLoading } = trpc.mentor.getRecentMessages.useQuery({ limit: 5 })
|
|
|
|
return (
|
|
<Card>
|
|
<CardHeader>
|
|
<CardTitle className="flex items-center gap-2 text-base">
|
|
<MessageCircle className="h-4 w-4" /> Recent Messages
|
|
</CardTitle>
|
|
</CardHeader>
|
|
<CardContent>
|
|
{isLoading ? (
|
|
<div className="space-y-2">
|
|
{[1, 2, 3].map((i) => (
|
|
<Skeleton key={i} className="h-12 w-full" />
|
|
))}
|
|
</div>
|
|
) : !data || data.unread.length === 0 ? (
|
|
<p className="text-muted-foreground text-sm">
|
|
No new messages. Your mentees will appear here when they reach out.
|
|
</p>
|
|
) : (
|
|
<ul className="space-y-3">
|
|
{data.unread.map((m) => (
|
|
<li key={m.id}>
|
|
<Link
|
|
href={`/mentor/workspace/${m.project.id}`}
|
|
className="hover:bg-muted/40 block rounded-md border p-3"
|
|
>
|
|
<div className="flex items-baseline justify-between gap-2">
|
|
<div className="text-sm font-medium">{m.sender.name ?? m.sender.email}</div>
|
|
<div className="text-muted-foreground text-xs">
|
|
{formatRelativePast(m.createdAt as unknown as Date)}
|
|
</div>
|
|
</div>
|
|
<div className="text-muted-foreground mt-0.5 text-xs">{m.project.title}</div>
|
|
<div className="mt-1 line-clamp-2 text-sm">{m.message}</div>
|
|
</Link>
|
|
</li>
|
|
))}
|
|
</ul>
|
|
)}
|
|
</CardContent>
|
|
</Card>
|
|
)
|
|
}
|