feat(contribute): upload event images to OneDrive before submission

- ApiClient.uploadFile() — multipart POST to /v1/upload/file (60s timeout)
- ApiEndpoints.uploadFile — points to Node.js upload endpoint
- GamificationService.submitContribution() now uploads each picked image
  to OneDrive via the server upload pipeline, then passes the returned
  { fileId, url, ... } objects as `media` in the submission body
  (replaces broken behaviour of sending local device paths as strings)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-08 21:12:49 +05:30
parent 479fe5e119
commit c40e600937
7 changed files with 190 additions and 9 deletions

View File

@@ -129,6 +129,32 @@ class EventsService {
return list;
}
/// Featured events for the home screen hero carousel.
Future<List<EventModel>> getFeaturedEvents() async {
final res = await _api.post(ApiEndpoints.featuredEvents, requiresAuth: false);
final events = res['events'] ?? res['data'] ?? [];
if (events is List) {
return events
.whereType<Map<String, dynamic>>()
.map((e) => EventModel.fromJson(e))
.toList();
}
return [];
}
/// Top events for the home screen top events section.
Future<List<EventModel>> getTopEvents() async {
final res = await _api.post(ApiEndpoints.topEvents, requiresAuth: false);
final events = res['events'] ?? res['data'] ?? [];
if (events is List) {
return events
.whereType<Map<String, dynamic>>()
.map((e) => EventModel.fromJson(e))
.toList();
}
return [];
}
/// Events by month and year for calendar (POST to /events/events-by-month-year/)
Future<Map<String, dynamic>> getEventsByMonthYear(String month, int year) async {
final res = await _api.post(ApiEndpoints.eventsByMonth, body: {'month': month, 'year': year}, requiresAuth: false);