Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion lib/screens/tickets/create_ticket_screen.dart
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ class _CreateTicketScreenState extends State<CreateTicketScreen> {
}

Future<void> _createTicket() async {
if (!_formKey.currentState!.validate()) return;
if (!(_formKey.currentState?.validate() ?? false)) return;

setState(() {
_isLoading = true;
Expand Down
62 changes: 55 additions & 7 deletions lib/services/supabase_service.dart
Original file line number Diff line number Diff line change
Expand Up @@ -1398,8 +1398,12 @@ class SupabaseService {
if (user == null) return null;

// Get task details
final taskResponse =
await _client.from('tasks').select('*').eq('id', taskId).single();
final taskResponseList =
await _client.from('tasks').select('*').eq('id', taskId);
if (taskResponseList.isEmpty) {
throw Exception('Task not found');
}
final taskResponse = taskResponseList.first;

// Get task comments
final commentsResponse = await _client
Expand Down Expand Up @@ -1719,6 +1723,7 @@ class SupabaseService {
}
}


// Create a new ticket
Future<Map<String, dynamic>> createTicket({
required String title,
Expand Down Expand Up @@ -1754,7 +1759,7 @@ class SupabaseService {

final teamId = userProfile['team_id'];

// Create the ticket
// Create the ticket payload
final Map<String, dynamic> ticketData = {
'title': title,
'description': description,
Expand All @@ -1780,12 +1785,52 @@ class SupabaseService {
};
}

final createdTicket = response[0];
final ticketId = createdTicket['id'];

// Try creating GitHub issue (non-blocking)
try {
if (ticketId != null) {
final ticketNumber = createdTicket['ticket_number'] ?? 'UNKNOWN';

final safeDescription =
(description != null && description.trim().isNotEmpty)
? description.trim()
: 'No description provided.';

final githubResponse = await _client.functions.invoke(
'create-github-issue',
body: {
'title': title,
'description': safeDescription,
'ticketNumber': ticketNumber,
},
);

final data = githubResponse.data;

if (data is Map &&
data['issue_number'] != null &&
data['issue_url'] != null) {
await _client
.from('tickets')
.update({
'github_issue_number': data['issue_number'],
'github_issue_url': data['issue_url'],
})
.eq('id', ticketId);
}
}
} catch (e) {
debugPrint('GitHub issue creation failed: $e');
}

// Refresh tickets
await getTickets();

return {
'success': true,
'ticket': response[0],
'ticket': createdTicket,
};
} catch (e) {
debugPrint('Error creating ticket: $e');
Expand Down Expand Up @@ -2282,11 +2327,14 @@ class SupabaseService {
if (user == null) return null;

// Get meeting details
final meetingResponse = await _client
final meetingResponseList = await _client
.from('meetings')
.select('*')
.eq('id', meetingId)
.single();
.eq('id', meetingId);
if (meetingResponseList.isEmpty) {
throw Exception('Meeting not found');
}
final meetingResponse = meetingResponseList.first;

// Get creator info
String? createdById = meetingResponse['created_by'];
Expand Down
3 changes: 3 additions & 0 deletions supabase/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
GITHUB_TOKEN=
GITHUB_OWNER=
GITHUB_REPO=
58 changes: 58 additions & 0 deletions supabase/functions/create-github-issue/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import { serve } from "https://deno.land/std@0.168.0/http/server.ts";

serve(async (req: Request) => {
try {
const body = await req.json();
const title = body.title;
const description = body.description;
const ticketNumber = body.ticketNumber;

const githubToken = Deno.env.get("GITHUB_TOKEN");
const githubRepo = Deno.env.get("GITHUB_REPO");
const githubOwner = Deno.env.get("GITHUB_OWNER");

if (!githubToken || !githubOwner || !githubRepo) {
return new Response(
JSON.stringify({ error: "GitHub configuration missing" }),
{ status: 500 }
);
}

const githubResponse = await fetch(
`https://api.github.com/repos/${githubOwner}/${githubRepo}/issues`,
{
method: "POST",
headers: {
"Authorization": `Bearer ${githubToken}`,
"Content-Type": "application/json",
"Accept": "application/vnd.github+json"
},
body: JSON.stringify({
title: title,
body: `Created from Ell-ena

Ticket: ${ticketNumber}

Description:
${description}`
})
}
);

const data = await githubResponse.json();

return new Response(
JSON.stringify({
issue_number: data.number,
issue_url: data.html_url
}),
{ headers: { "Content-Type": "application/json" } }
);

} catch (error) {
return new Response(
JSON.stringify({ error: String(error) }),
{ status: 500 }
);
}
});
3 changes: 3 additions & 0 deletions supabase/migrations/add_github_fields_to_tickets.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
ALTER TABLE tickets
ADD COLUMN github_issue_number INTEGER,
ADD COLUMN github_issue_url TEXT;