feat: Add contact fields to hackathon and submission data; update registration service to handle string ID
This commit is contained in:
@@ -338,9 +338,17 @@ async fn main() -> Result<(), Box<dyn Error>> {
|
||||
project_name: Some(project_name.into()),
|
||||
description: Some(description.into()),
|
||||
repository_url,
|
||||
upload_file_url: None,
|
||||
demo_url,
|
||||
slides_url,
|
||||
technologies: Some(technologies),
|
||||
contact_instagram: None,
|
||||
contact_twitter: None,
|
||||
contact_linkedin: None,
|
||||
contact_facebook: None,
|
||||
contact_youtube: None,
|
||||
contact_tiktok: None,
|
||||
contact_other: None,
|
||||
submission_status: Some(submission_status),
|
||||
submitted_at: Some(DateTime::parse_from_rfc3339(submitted_at)?.with_timezone(&Utc)),
|
||||
is_deleted: false,
|
||||
|
||||
@@ -402,9 +402,17 @@ async fn main() -> Result<(), Box<dyn Error>> {
|
||||
project_name: Some(project_name.into()),
|
||||
description: Some(description.into()),
|
||||
repository_url,
|
||||
upload_file_url: None,
|
||||
demo_url,
|
||||
slides_url,
|
||||
technologies: Some(technologies),
|
||||
contact_instagram: None,
|
||||
contact_twitter: None,
|
||||
contact_linkedin: None,
|
||||
contact_facebook: None,
|
||||
contact_youtube: None,
|
||||
contact_tiktok: None,
|
||||
contact_other: None,
|
||||
submission_status: Some(submission_status),
|
||||
judge_feedback: None,
|
||||
submitted_at: Some(DateTime::parse_from_rfc3339(submitted_at)?.with_timezone(&Utc)),
|
||||
|
||||
@@ -10,8 +10,7 @@ use super::hackathon_schema::SubmissionStatus;
|
||||
use crate::v1::hackathon::HackathonRepository;
|
||||
use crate::{AppState, ResponseSuccessDto, ErrorDto};
|
||||
use imphnen_entities::{PermissionsEnum, UsersDetailQueryDto};
|
||||
use imphnen_libs::{MetaRequestDto, ResponseListSuccessDto, ValidatedJson};
|
||||
use imphnen_iam::require_permissions;
|
||||
use imphnen_libs::{MetaRequestDto, ResponseListSuccessDto};
|
||||
use axum::{
|
||||
extract::{Extension, Path, Query},
|
||||
http::StatusCode,
|
||||
|
||||
@@ -1,17 +1,14 @@
|
||||
use super::notification_dto::{
|
||||
DeleteNotificationResponseDto, MarkAllAsReadResponseDto, MarkAsReadResponseDto,
|
||||
NotificationDto, NotificationListQueryDto, NotificationListResponseDto,
|
||||
DeleteNotificationResponseDto, MarkAllAsReadResponseDto, MarkAsReadResponseDto, NotificationListQueryDto, NotificationListResponseDto,
|
||||
UnreadCountResponseDto,
|
||||
};
|
||||
use super::notification_service::Service;
|
||||
use axum::{
|
||||
extract::{Extension, Path, Query},
|
||||
http::{HeaderMap, Response, StatusCode},
|
||||
response::IntoResponse,
|
||||
routing::{delete, get, put},
|
||||
Router, body::Body,
|
||||
};
|
||||
use imphnen_entities::common_dto::ResponseSuccessDto;
|
||||
use imphnen_libs::AppState;
|
||||
use imphnen_utils::{extract_email::extract_email, response_format::common_response};
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use crate::v1::notifications::notification_schema::NotificationSchema;
|
||||
use imphnen_libs::AppState;
|
||||
use imphnen_utils::{get_id, make_thing};
|
||||
use imphnen_utils::get_id;
|
||||
use surrealdb::sql::Thing;
|
||||
|
||||
pub struct Repository<'a> {
|
||||
|
||||
@@ -57,7 +57,7 @@ pub async fn post_register_hackathon(
|
||||
let hackathon_id = make_thing_from_enum(ResourceEnum::Hackathons, &id);
|
||||
|
||||
let service = RegistrationsService::new(&state);
|
||||
service.register_hackathon(&hackathon_id, &user_email, data).await
|
||||
service.register_hackathon(&hackathon_id, &id, &user_email, data).await
|
||||
}
|
||||
|
||||
// ============================================
|
||||
|
||||
@@ -105,8 +105,7 @@ impl<'a> RegistrationsRepository<'a> {
|
||||
WHERE hackathon_id = $hackathon_id
|
||||
AND status = $status
|
||||
AND is_deleted = false
|
||||
FETCH hackathon_id, user_id, team_id
|
||||
ORDER BY registration_date DESC
|
||||
FETCH hackathon_id, user_id, team_id;
|
||||
"#
|
||||
} else {
|
||||
r#"
|
||||
@@ -129,8 +128,7 @@ impl<'a> RegistrationsRepository<'a> {
|
||||
FROM hackathon_registrations
|
||||
WHERE hackathon_id = $hackathon_id
|
||||
AND is_deleted = false
|
||||
FETCH hackathon_id, user_id, team_id
|
||||
ORDER BY registration_date DESC
|
||||
FETCH hackathon_id, user_id, team_id;
|
||||
"#
|
||||
};
|
||||
|
||||
@@ -172,7 +170,7 @@ impl<'a> RegistrationsRepository<'a> {
|
||||
.map_err(|e| format!("Failed to parse registrations: {}", e))?;
|
||||
|
||||
// Convert to full DTO with all fetched data
|
||||
let registrations = simple
|
||||
let mut registrations: Vec<RegistrationListQueryDto> = simple
|
||||
.into_iter()
|
||||
.map(|r| RegistrationListQueryDto {
|
||||
id: r.id,
|
||||
@@ -185,7 +183,7 @@ impl<'a> RegistrationsRepository<'a> {
|
||||
team_name: r.team_name,
|
||||
status: r.status,
|
||||
role: r.role,
|
||||
registration_date: r.registration_date,
|
||||
registration_date: r.registration_date.clone(),
|
||||
checked_in: r.checked_in,
|
||||
check_in_time: r.check_in_time,
|
||||
experience_level: r.experience_level,
|
||||
@@ -193,6 +191,9 @@ impl<'a> RegistrationsRepository<'a> {
|
||||
})
|
||||
.collect();
|
||||
|
||||
// Sort by registration_date DESC (newest first)
|
||||
registrations.sort_by(|a, b| b.registration_date.cmp(&a.registration_date));
|
||||
|
||||
Ok(registrations)
|
||||
}
|
||||
|
||||
@@ -219,8 +220,7 @@ impl<'a> RegistrationsRepository<'a> {
|
||||
FROM hackathon_registrations
|
||||
WHERE user_id = $user_id
|
||||
AND is_deleted = false
|
||||
FETCH hackathon_id, team_id
|
||||
ORDER BY registration_date DESC
|
||||
FETCH hackathon_id, team_id;
|
||||
"#;
|
||||
|
||||
let user_id_clone = user_id.clone();
|
||||
@@ -251,7 +251,7 @@ impl<'a> RegistrationsRepository<'a> {
|
||||
.map_err(|e| format!("Failed to parse user hackathons: {}", e))?;
|
||||
|
||||
// Convert to full DTO with all fetched data
|
||||
let hackathons = simple
|
||||
let mut hackathons: Vec<UserHackathonQueryDto> = simple
|
||||
.into_iter()
|
||||
.map(|h| UserHackathonQueryDto {
|
||||
registration_id: h.registration_id,
|
||||
@@ -262,13 +262,16 @@ impl<'a> RegistrationsRepository<'a> {
|
||||
end_date: h.end_date,
|
||||
status: h.status,
|
||||
role: h.role,
|
||||
registration_date: h.registration_date,
|
||||
registration_date: h.registration_date.clone(),
|
||||
checked_in: h.checked_in,
|
||||
team_id: h.team_id,
|
||||
team_name: h.team_name,
|
||||
})
|
||||
.collect();
|
||||
|
||||
// Sort by registration_date DESC (newest first)
|
||||
hackathons.sort_by(|a, b| b.registration_date.cmp(&a.registration_date));
|
||||
|
||||
Ok(hackathons)
|
||||
}
|
||||
|
||||
|
||||
@@ -32,6 +32,7 @@ impl<'a> RegistrationsService<'a> {
|
||||
pub async fn register_hackathon(
|
||||
&self,
|
||||
hackathon_id: &Thing,
|
||||
hackathon_id_str: &str,
|
||||
user_email: &str,
|
||||
data: RegistrationRequestDto,
|
||||
) -> Response {
|
||||
@@ -47,14 +48,17 @@ impl<'a> RegistrationsService<'a> {
|
||||
|
||||
// Check if hackathon exists
|
||||
let hackathon_repo = HackathonRepository::new(self.state);
|
||||
match hackathon_repo.get_by_id(hackathon_id).await {
|
||||
Ok(None) => {
|
||||
return common_response(StatusCode::NOT_FOUND, "Hackathon not found");
|
||||
}
|
||||
// Use the raw string ID from the path parameter
|
||||
match hackathon_repo.get_hackathon_by_id(hackathon_id_str.to_string()).await {
|
||||
Err(e) => {
|
||||
// Method returns error if hackathon not found or is deleted
|
||||
let error_msg = e.to_string();
|
||||
if error_msg.contains("not found") || error_msg.contains("Hackathon not found") {
|
||||
return common_response(StatusCode::NOT_FOUND, "Hackathon not found");
|
||||
}
|
||||
return common_response(StatusCode::INTERNAL_SERVER_ERROR, &format!("Failed to verify hackathon: {}", e));
|
||||
}
|
||||
Ok(Some(_)) => {} // Hackathon exists, continue
|
||||
Ok(_) => {} // Hackathon exists, continue
|
||||
}
|
||||
|
||||
// Check if user already registered
|
||||
|
||||
Reference in New Issue
Block a user