Skip to content

Commit b1e31ea

Browse files
authored
Merge pull request #289 from codeunia-dev/feat/adminsupport
feat(support): Enhance support ticket detail page with reply history
2 parents 4fdda6e + a43c788 commit b1e31ea

File tree

3 files changed

+108
-5
lines changed

3 files changed

+108
-5
lines changed

app/admin/support/[id]/page.tsx

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,22 @@ import {
2121
import { toast } from 'sonner'
2222
import Link from 'next/link'
2323

24+
interface TicketReply {
25+
id: string
26+
ticket_id: string
27+
admin_id: string
28+
message: string
29+
created_at: string
30+
updated_at: string
31+
admin?: {
32+
id: string
33+
email: string
34+
first_name?: string
35+
last_name?: string
36+
avatar_url?: string
37+
}
38+
}
39+
2440
interface SupportTicket {
2541
id: string
2642
user_id: string
@@ -37,6 +53,7 @@ interface SupportTicket {
3753
last_name?: string
3854
avatar_url?: string
3955
}
56+
replies?: TicketReply[]
4057
}
4158

4259
export default function TicketDetailPage() {
@@ -235,6 +252,55 @@ export default function TicketDetailPage() {
235252
</CardContent>
236253
</Card>
237254

255+
{/* Reply History */}
256+
{ticket.replies && ticket.replies.length > 0 && (
257+
<Card>
258+
<CardHeader>
259+
<CardTitle className="flex items-center gap-2">
260+
<MessageSquare className="h-5 w-5 text-purple-500" />
261+
Reply History ({ticket.replies.length})
262+
</CardTitle>
263+
<CardDescription>
264+
Previous responses sent to the user
265+
</CardDescription>
266+
</CardHeader>
267+
<CardContent className="space-y-4">
268+
{ticket.replies.map((reply, index) => (
269+
<div
270+
key={reply.id}
271+
className="border-l-4 border-purple-500/30 bg-purple-500/5 rounded-r-lg p-4 space-y-2"
272+
>
273+
<div className="flex items-center justify-between">
274+
<div className="flex items-center gap-2">
275+
<div className="h-8 w-8 rounded-full bg-gradient-to-br from-purple-500 to-blue-600 flex items-center justify-center text-white text-sm font-semibold">
276+
{reply.admin?.first_name?.[0] || reply.admin?.email[0].toUpperCase() || 'A'}
277+
</div>
278+
<div>
279+
<p className="text-sm font-medium">
280+
{reply.admin?.first_name && reply.admin?.last_name
281+
? `${reply.admin.first_name} ${reply.admin.last_name}`
282+
: reply.admin?.email || 'Admin'}
283+
</p>
284+
<p className="text-xs text-muted-foreground">
285+
{new Date(reply.created_at).toLocaleString()}
286+
</p>
287+
</div>
288+
</div>
289+
<Badge variant="outline" className="text-xs">
290+
Reply #{index + 1}
291+
</Badge>
292+
</div>
293+
<div className="pl-10">
294+
<p className="text-sm text-foreground whitespace-pre-wrap">
295+
{reply.message}
296+
</p>
297+
</div>
298+
</div>
299+
))}
300+
</CardContent>
301+
</Card>
302+
)}
303+
238304
{/* Reply to User */}
239305
<Card className="border-blue-500/20 bg-blue-500/5">
240306
<CardHeader>

app/api/admin/support/tickets/[id]/reply/route.ts

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -99,12 +99,28 @@ export async function POST(
9999

100100
console.log('✅ Reply email sent successfully')
101101

102-
// TODO: Save reply to database (for reply history)
103-
// This would go in a support_ticket_replies table
102+
// Save reply to database for history
103+
const { data: reply, error: replyError } = await supabase
104+
.from('support_ticket_replies')
105+
.insert({
106+
ticket_id: ticket.id,
107+
admin_id: user.id,
108+
message: message.trim()
109+
})
110+
.select()
111+
.single()
112+
113+
if (replyError) {
114+
console.error('❌ Failed to save reply to database:', replyError)
115+
// Don't fail the request since email was sent successfully
116+
} else {
117+
console.log('✅ Reply saved to database:', reply.id)
118+
}
104119

105120
return NextResponse.json({
106121
success: true,
107-
message: 'Reply sent successfully'
122+
message: 'Reply sent successfully',
123+
reply
108124
})
109125
} catch (error) {
110126
console.error('Error in reply API:', error)

app/api/admin/support/tickets/[id]/route.ts

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,10 +47,31 @@ export async function GET(
4747
.eq('id', ticket.user_id)
4848
.single()
4949

50-
// Combine ticket with user data
50+
// Get reply history
51+
const { data: replies } = await supabase
52+
.from('support_ticket_replies')
53+
.select('*')
54+
.eq('ticket_id', id)
55+
.order('created_at', { ascending: true })
56+
57+
// Get admin profiles for replies
58+
const adminIds = [...new Set(replies?.map(r => r.admin_id) || [])]
59+
const { data: adminProfiles } = await supabase
60+
.from('profiles')
61+
.select('id, email, first_name, last_name, avatar_url')
62+
.in('id', adminIds)
63+
64+
// Map admin data to replies
65+
const repliesWithAdmins = replies?.map(reply => ({
66+
...reply,
67+
admin: adminProfiles?.find(p => p.id === reply.admin_id) || null
68+
})) || []
69+
70+
// Combine ticket with user data and replies
5171
const ticketWithUser = {
5272
...ticket,
53-
user: userProfile || null
73+
user: userProfile || null,
74+
replies: repliesWithAdmins
5475
}
5576

5677
return NextResponse.json({ ticket: ticketWithUser })

0 commit comments

Comments
 (0)