mod auth; use actix_cors::Cors; use actix_files::Files; use actix_web::{ get, http::header, web, App, HttpResponse, HttpServer, Responder, }; use dotenv::dotenv; use env_logger::{Builder, Env}; use sqlx::postgres::PgPoolOptions; use rust_decimal::Decimal; use bigdecimal::BigDecimal; use serde_json::json; #[derive(sqlx::FromRow, serde::Serialize)] struct Book { id: i32, tytul: String, autor: String, cena: BigDecimal, obraz_url: Option } #[get("/api/ksiazki")] async fn get_ksiazki(pool: web::Data) -> impl Responder { match sqlx::query_as!( Book, r#"SELECT id, tytul, autor, cena, obraz_url FROM ksiazki"# ) .fetch_all(pool.get_ref()) .await { Ok(books) => HttpResponse::Ok().json(books), Err(e) => { log::error!("Błąd bazy danych: {:?}", e); HttpResponse::InternalServerError().body(format!("Błąd: {}", e)) } } } #[get("/api/check-auth")] async fn check_auth() -> impl Responder { HttpResponse::Ok().json(json!({ "authenticated": false, "user": null })) } #[actix_web::main] async fn main() -> std::io::Result<()> { // Inicjalizacja loggera Builder::from_env(Env::default().default_filter_or("debug")).init(); // Ładowanie zmiennych środowiskowych dotenv().ok(); let database_url = std::env::var("DATABASE_URL") .expect("DATABASE_URL must be set in .env"); // Utwórz pulę połączeń let pool = PgPoolOptions::new() .max_connections(5) .connect(&database_url) .await .expect("Failed to create pool"); HttpServer::new(move || { let cors = Cors::default() .allow_any_origin() .allowed_methods(vec!["GET", "POST"]) .allowed_headers(vec![ header::CONTENT_TYPE, header::AUTHORIZATION, header::ACCEPT, header::HeaderName::from_static("content-type"), ]); App::new() .app_data(web::Data::new(pool.clone())) // Dodaj pulę jako globalny stan .wrap(cors) .wrap(actix_web::middleware::Logger::default()) .service(get_ksiazki) .service(auth::rejestracja) .service(auth::login) .service(Files::new("/", "./static").index_file("index.html")) }) .bind("0.0.0.0:7999")? .run() .await }