Skip to content

Commit 4a5846f

Browse files
authored
Merge pull request #287 from codeunia-dev/feat/adminsupport
feat(support): Enhance support ticket email notifications and workflows
2 parents df92bd8 + b7b5a59 commit 4a5846f

File tree

4 files changed

+430
-2
lines changed

4 files changed

+430
-2
lines changed

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

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { NextRequest, NextResponse } from 'next/server'
22
import { createClient } from '@/lib/supabase/server'
3+
import { getStatusUpdateEmail, sendEmail } from '@/lib/email/support-emails'
34

45
export async function GET(
56
request: NextRequest,
@@ -88,6 +89,19 @@ export async function PATCH(
8889
return NextResponse.json({ error: 'Invalid status' }, { status: 400 })
8990
}
9091

92+
// Get current ticket to check old status
93+
const { data: currentTicket } = await supabase
94+
.from('support_tickets')
95+
.select('*, user:profiles!user_id(email, first_name, last_name)')
96+
.eq('id', id)
97+
.single()
98+
99+
if (!currentTicket) {
100+
return NextResponse.json({ error: 'Ticket not found' }, { status: 404 })
101+
}
102+
103+
const oldStatus = currentTicket.status
104+
91105
// Update ticket status
92106
const { data: ticket, error } = await supabase
93107
.from('support_tickets')
@@ -101,6 +115,26 @@ export async function PATCH(
101115
return NextResponse.json({ error: 'Failed to update ticket' }, { status: 500 })
102116
}
103117

118+
// Send status update email to user (only if status actually changed)
119+
if (oldStatus !== status && currentTicket.user) {
120+
const userName = currentTicket.user.first_name || currentTicket.user.email?.split('@')[0] || 'User'
121+
const userEmail = currentTicket.user.email || ''
122+
123+
const statusEmail = getStatusUpdateEmail({
124+
userName,
125+
ticketId: ticket.id,
126+
subject: ticket.subject,
127+
oldStatus,
128+
newStatus: status
129+
})
130+
131+
await sendEmail({
132+
to: userEmail,
133+
subject: statusEmail.subject,
134+
html: statusEmail.html
135+
})
136+
}
137+
104138
return NextResponse.json({ ticket })
105139
} catch (error) {
106140
console.error('Error in ticket update API:', error)

app/api/support/bug-report/route.ts

Lines changed: 58 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { NextRequest, NextResponse } from 'next/server'
22
import { createClient } from '@/lib/supabase/server'
3+
import { getUserConfirmationEmail, getSupportTeamNotificationEmail, sendEmail } from '@/lib/email/support-emails'
34

45
export async function POST(request: NextRequest) {
56
try {
@@ -18,8 +19,15 @@ export async function POST(request: NextRequest) {
1819
return NextResponse.json({ error: 'Title and description are required' }, { status: 400 })
1920
}
2021

22+
// Get user profile
23+
const { data: profile } = await supabase
24+
.from('profiles')
25+
.select('email, first_name, last_name')
26+
.eq('id', user.id)
27+
.single()
28+
2129
// Insert bug report into database
22-
const { error: insertError } = await supabase
30+
const { data: ticket, error: insertError } = await supabase
2331
.from('support_tickets')
2432
.insert({
2533
user_id: user.id,
@@ -28,12 +36,61 @@ export async function POST(request: NextRequest) {
2836
message: description,
2937
status: 'open',
3038
})
39+
.select()
40+
.single()
3141

3242
if (insertError) {
3343
console.error('Error creating bug report:', insertError)
3444
return NextResponse.json({ error: 'Failed to submit bug report' }, { status: 500 })
3545
}
3646

47+
// Send confirmation email to user
48+
const userName = profile?.first_name || profile?.email?.split('@')[0] || 'User'
49+
const userEmail = profile?.email || user.email || ''
50+
51+
const confirmationEmail = getUserConfirmationEmail({
52+
userName,
53+
ticketId: ticket.id,
54+
ticketType: 'bug',
55+
subject: title,
56+
message: description
57+
})
58+
59+
await sendEmail({
60+
to: userEmail,
61+
subject: confirmationEmail.subject,
62+
html: confirmationEmail.html
63+
})
64+
65+
// Send notification to support team
66+
const supportEmail = getSupportTeamNotificationEmail({
67+
ticketId: ticket.id,
68+
ticketType: 'bug',
69+
subject: title,
70+
message: description,
71+
userEmail,
72+
userName: `${profile?.first_name || ''} ${profile?.last_name || ''}`.trim() || userName
73+
})
74+
75+
// Get support email(s) - can be comma-separated for multiple recipients
76+
const supportEmailAddress = process.env.SUPPORT_EMAIL
77+
78+
if (!supportEmailAddress) {
79+
console.warn('⚠️ SUPPORT_EMAIL not configured in environment variables')
80+
} else {
81+
console.log('📧 Sending support team notification to:', supportEmailAddress)
82+
83+
const supportEmailResult = await sendEmail({
84+
to: supportEmailAddress,
85+
subject: supportEmail.subject,
86+
html: supportEmail.html
87+
})
88+
89+
if (!supportEmailResult.success) {
90+
console.error('⚠️ Failed to send support team notification:', supportEmailResult.error)
91+
}
92+
}
93+
3794
return NextResponse.json({ success: true, message: 'Bug report submitted successfully' })
3895
} catch (error) {
3996
console.error('Error in bug report API:', error)

app/api/support/contact/route.ts

Lines changed: 58 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { NextRequest, NextResponse } from 'next/server'
22
import { createClient } from '@/lib/supabase/server'
3+
import { getUserConfirmationEmail, getSupportTeamNotificationEmail, sendEmail } from '@/lib/email/support-emails'
34

45
export async function POST(request: NextRequest) {
56
try {
@@ -18,8 +19,15 @@ export async function POST(request: NextRequest) {
1819
return NextResponse.json({ error: 'Subject and message are required' }, { status: 400 })
1920
}
2021

22+
// Get user profile
23+
const { data: profile } = await supabase
24+
.from('profiles')
25+
.select('email, first_name, last_name')
26+
.eq('id', user.id)
27+
.single()
28+
2129
// Insert contact request into database
22-
const { error: insertError } = await supabase
30+
const { data: ticket, error: insertError } = await supabase
2331
.from('support_tickets')
2432
.insert({
2533
user_id: user.id,
@@ -28,12 +36,61 @@ export async function POST(request: NextRequest) {
2836
message,
2937
status: 'open',
3038
})
39+
.select()
40+
.single()
3141

3242
if (insertError) {
3343
console.error('Error creating support ticket:', insertError)
3444
return NextResponse.json({ error: 'Failed to submit contact request' }, { status: 500 })
3545
}
3646

47+
// Send confirmation email to user
48+
const userName = profile?.first_name || profile?.email?.split('@')[0] || 'User'
49+
const userEmail = profile?.email || user.email || ''
50+
51+
const confirmationEmail = getUserConfirmationEmail({
52+
userName,
53+
ticketId: ticket.id,
54+
ticketType: 'contact',
55+
subject,
56+
message
57+
})
58+
59+
await sendEmail({
60+
to: userEmail,
61+
subject: confirmationEmail.subject,
62+
html: confirmationEmail.html
63+
})
64+
65+
// Send notification to support team
66+
const supportEmail = getSupportTeamNotificationEmail({
67+
ticketId: ticket.id,
68+
ticketType: 'contact',
69+
subject,
70+
message,
71+
userEmail,
72+
userName: `${profile?.first_name || ''} ${profile?.last_name || ''}`.trim() || userName
73+
})
74+
75+
// Get support email(s) - can be comma-separated for multiple recipients
76+
const supportEmailAddress = process.env.SUPPORT_EMAIL
77+
78+
if (!supportEmailAddress) {
79+
console.warn('⚠️ SUPPORT_EMAIL not configured in environment variables')
80+
} else {
81+
console.log('📧 Sending support team notification to:', supportEmailAddress)
82+
83+
const supportEmailResult = await sendEmail({
84+
to: supportEmailAddress,
85+
subject: supportEmail.subject,
86+
html: supportEmail.html
87+
})
88+
89+
if (!supportEmailResult.success) {
90+
console.error('⚠️ Failed to send support team notification:', supportEmailResult.error)
91+
}
92+
}
93+
3794
return NextResponse.json({ success: true, message: 'Contact request submitted successfully' })
3895
} catch (error) {
3996
console.error('Error in contact API:', error)

0 commit comments

Comments
 (0)