feat: creating invites frontend
This commit is contained in:
parent
d2f74d0296
commit
2f7bc9e6c5
@ -11,4 +11,5 @@ class ApiConstants {
|
||||
// Invitation endpoints
|
||||
static const String getAllInvitationsEndpoint = '/invitations/all';
|
||||
static const String acceptInvitationEndpoint = '/invitations/accept';
|
||||
static const String createInvitationEndpoint = '/invitations/create';
|
||||
}
|
||||
|
||||
@ -459,11 +459,14 @@ class _InvitationsPageState extends State<InvitationsPage>
|
||||
),
|
||||
),
|
||||
floatingActionButton: FloatingActionButton(
|
||||
onPressed: () {
|
||||
Navigator.push(
|
||||
onPressed: () async {
|
||||
final result = await Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(builder: (context) => CreateInvitationPage()),
|
||||
);
|
||||
if (result == true) {
|
||||
_loadInvitations();
|
||||
}
|
||||
},
|
||||
backgroundColor: Color(0xFF6A4C93),
|
||||
child: Icon(Icons.add, color: Colors.white),
|
||||
@ -487,16 +490,17 @@ class _CreateInvitationPageState extends State<CreateInvitationPage> {
|
||||
DateTime? _selectedDate;
|
||||
TimeOfDay? _selectedTime;
|
||||
int? _selectedTagIndex;
|
||||
bool _isSubmitting = false;
|
||||
|
||||
final List<Map<String, dynamic>> _availableTags = [
|
||||
{"name": "Sports", "color_hex": "#FF6B35", "icon_name": "sports_soccer"},
|
||||
{"name": "Food", "color_hex": "#F7931E", "icon_name": "restaurant"},
|
||||
{"name": "Gaming", "color_hex": "#FFD23F", "icon_name": "games"},
|
||||
{"name": "Study", "color_hex": "#06FFA5", "icon_name": "menu_book"},
|
||||
{"name": "Social", "color_hex": "#118AB2", "icon_name": "group"},
|
||||
{"name": "Travel", "color_hex": "#06D6A0", "icon_name": "flight"},
|
||||
{"name": "Music", "color_hex": "#8E44AD", "icon_name": "music_note"},
|
||||
{"name": "Movies", "color_hex": "#E74C3C", "icon_name": "movie"},
|
||||
{"id": 1, "name": "Sports", "color_hex": "#FF6B35", "icon_name": "sports_soccer"},
|
||||
{"id": 2, "name": "Food", "color_hex": "#F7931E", "icon_name": "restaurant"},
|
||||
{"id": 3, "name": "Gaming", "color_hex": "#FFD23F", "icon_name": "games"},
|
||||
{"id": 4, "name": "Study", "color_hex": "#06FFA5", "icon_name": "menu_book"},
|
||||
{"id": 5, "name": "Social", "color_hex": "#118AB2", "icon_name": "group"},
|
||||
{"id": 6, "name": "Travel", "color_hex": "#06D6A0", "icon_name": "flight"},
|
||||
{"id": 7, "name": "Music", "color_hex": "#8E44AD", "icon_name": "music_note"},
|
||||
{"id": 8, "name": "Movies", "color_hex": "#E74C3C", "icon_name": "movie"},
|
||||
];
|
||||
|
||||
@override
|
||||
@ -577,7 +581,7 @@ class _CreateInvitationPageState extends State<CreateInvitationPage> {
|
||||
}
|
||||
}
|
||||
|
||||
void _handleSubmit() {
|
||||
Future<void> _handleSubmit() async {
|
||||
if (_formKey.currentState!.validate()) {
|
||||
if (_selectedTagIndex == null) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
@ -589,28 +593,54 @@ class _CreateInvitationPageState extends State<CreateInvitationPage> {
|
||||
return;
|
||||
}
|
||||
|
||||
setState(() {
|
||||
_isSubmitting = true;
|
||||
});
|
||||
|
||||
DateTime? combinedDateTime;
|
||||
if (_selectedDate != null) {
|
||||
if (_selectedTime != null) {
|
||||
combinedDateTime = DateTime(
|
||||
_selectedDate!.year,
|
||||
_selectedDate!.month,
|
||||
_selectedDate!.day,
|
||||
_selectedTime!.hour,
|
||||
_selectedTime!.minute,
|
||||
);
|
||||
} else {
|
||||
combinedDateTime = _selectedDate;
|
||||
}
|
||||
}
|
||||
|
||||
final invitationData = {
|
||||
"title": _titleController.text.trim(),
|
||||
"description": _descriptionController.text.trim(),
|
||||
"date": _selectedDate?.toIso8601String(),
|
||||
"time": _selectedTime != null
|
||||
? "${_selectedTime!.hour}:${_selectedTime!.minute.toString().padLeft(2, '0')}"
|
||||
: null,
|
||||
"dateTime": combinedDateTime?.toIso8601String(),
|
||||
"location": _locationController.text.trim().isEmpty
|
||||
? null
|
||||
: _locationController.text.trim(),
|
||||
"max_participants": int.parse(_maxParticipantsController.text),
|
||||
"tag": _availableTags[_selectedTagIndex!],
|
||||
"maxParticipants": int.parse(_maxParticipantsController.text),
|
||||
"tagId": _availableTags[_selectedTagIndex!]["id"],
|
||||
};
|
||||
|
||||
print("Invitation JSON: $invitationData");
|
||||
final result = await InvitationsService.createInvitation(invitationData);
|
||||
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
content: Text('Invitation created! Check console for JSON output.'),
|
||||
backgroundColor: Color(0xFF6A4C93),
|
||||
),
|
||||
);
|
||||
if (mounted) {
|
||||
setState(() {
|
||||
_isSubmitting = false;
|
||||
});
|
||||
|
||||
if (result['success']) {
|
||||
Navigator.of(context).pop(true);
|
||||
} else {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
content: Text(result['message'] ?? 'Failed to create invitation'),
|
||||
backgroundColor: Colors.red,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -932,7 +962,7 @@ class _CreateInvitationPageState extends State<CreateInvitationPage> {
|
||||
Container(
|
||||
height: 56,
|
||||
child: ElevatedButton(
|
||||
onPressed: _handleSubmit,
|
||||
onPressed: _isSubmitting ? null : _handleSubmit,
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: Color(0xFF6A4C93),
|
||||
foregroundColor: Colors.white,
|
||||
@ -941,13 +971,22 @@ class _CreateInvitationPageState extends State<CreateInvitationPage> {
|
||||
),
|
||||
elevation: 2,
|
||||
),
|
||||
child: Text(
|
||||
'Create Invitation',
|
||||
style: TextStyle(
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
child: _isSubmitting
|
||||
? SizedBox(
|
||||
height: 20,
|
||||
width: 20,
|
||||
child: CircularProgressIndicator(
|
||||
strokeWidth: 2,
|
||||
valueColor: AlwaysStoppedAnimation<Color>(Colors.white),
|
||||
),
|
||||
)
|
||||
: Text(
|
||||
'Create Invitation',
|
||||
style: TextStyle(
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
|
||||
@ -85,4 +85,50 @@ class InvitationsService {
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
static Future<Map<String, dynamic>> createInvitation(Map<String, dynamic> invitationData) async {
|
||||
try {
|
||||
final response = await HttpService.post(
|
||||
ApiConstants.createInvitationEndpoint,
|
||||
invitationData,
|
||||
);
|
||||
|
||||
if (response.statusCode == 200) {
|
||||
final responseData = jsonDecode(response.body);
|
||||
if (responseData['status'] == true) {
|
||||
return {
|
||||
'success': true,
|
||||
'data': responseData['data'],
|
||||
'message': responseData['message'],
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
'success': false,
|
||||
'message': responseData['message'] ?? 'Failed to create invitation',
|
||||
};
|
||||
}
|
||||
} else if (response.statusCode == 401) {
|
||||
return {
|
||||
'success': false,
|
||||
'message': 'Session expired. Please login again.',
|
||||
};
|
||||
} else if (response.statusCode == 403) {
|
||||
return {
|
||||
'success': false,
|
||||
'message': 'Access denied. Invalid credentials.',
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
'success': false,
|
||||
'message': 'Server error (${response.statusCode})',
|
||||
};
|
||||
}
|
||||
} catch (e) {
|
||||
print('Error creating invitation: $e');
|
||||
return {
|
||||
'success': false,
|
||||
'message': 'Network error. Please check your connection.',
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user