use crate::AppState; use axum::{extract::{Path, State}, http::StatusCode, response::IntoResponse, routing::get, Json, Router}; use chrono::{DateTime, Utc}; use serde::Serialize; use uuid::Uuid; #[derive(Serialize)] pub struct AdminDeveloperList { pub id: Uuid, pub user_id: Uuid, pub first_name: String, pub last_name: String, pub email: String, pub phone: Option, pub status: String, pub bio: Option, pub experience_years: Option, pub custom_data: serde_json::Value, pub created_at: DateTime, pub updated_at: DateTime, } type AdminDeveloperDetail = AdminDeveloperList; pub fn router() -> Router { Router::new() .route("/", get(list_developers)) .route("/{id}", get(get_developer)) } async fn list_developers( State(state): State, ) -> Result { let developers = sqlx::query_as!( AdminDeveloperList, r#" SELECT d.id, d.user_id, d.bio, d.experience_years, d.custom_data, d.created_at, d.updated_at, u.first_name, u.last_name, u.email, u.phone, u.status FROM developer_profiles d JOIN users u ON d.user_id = u.id ORDER BY d.created_at DESC LIMIT 100 "# ) .fetch_all(&state.pool) .await .map_err(|e| (StatusCode::INTERNAL_SERVER_ERROR, format!("DB error: {e}")))?; Ok(Json(developers)) } async fn get_developer( State(state): State, Path(id): Path, ) -> Result { let developer = sqlx::query_as!( AdminDeveloperDetail, r#" SELECT d.id, d.user_id, d.bio, d.experience_years, d.custom_data, d.created_at, d.updated_at, u.first_name, u.last_name, u.email, u.phone, u.status FROM developer_profiles d JOIN users u ON d.user_id = u.id WHERE d.id = $1 "#, id ) .fetch_optional(&state.pool) .await .map_err(|e| (StatusCode::INTERNAL_SERVER_ERROR, format!("DB error: {e}")))?; match developer { Some(d) => Ok(Json(d)), None => Err((StatusCode::NOT_FOUND, "Developer not found".to_string())), } }