history-done

This commit is contained in:
Lheorvine 2025-05-25 17:52:16 +02:00
parent 1f414d0a70
commit 4fbbff2c12
5 changed files with 103 additions and 34 deletions

View file

@ -54,12 +54,21 @@ struct CartItem {
quantity: i32, quantity: i32,
} }
#[derive(sqlx::FromRow, Serialize)] #[derive(Serialize)]
struct Order { struct OrderWithItems {
id: i32, id: i32,
data_zamowienia: chrono::NaiveDateTime, // Zmiana na obowiązkowy typ data_zamowienia: NaiveDateTime,
suma_totalna: BigDecimal, suma_totalna: BigDecimal,
status: Option<String>, status: Option<String>,
items: Vec<OrderItem>,
}
#[derive(sqlx::FromRow, Serialize)]
struct OrderItem {
tytul: String,
autor: String,
ilosc: i32,
cena: BigDecimal,
} }
#[derive(Deserialize)] #[derive(Deserialize)]
@ -333,26 +342,51 @@ async fn get_order_history(
req: HttpRequest, req: HttpRequest,
pool: web::Data<sqlx::PgPool>, pool: web::Data<sqlx::PgPool>,
) -> Result<HttpResponse, Error> { ) -> Result<HttpResponse, Error> {
let token = req.headers().get("Authorization") let user_id = validate_token(get_token(&req)).await?;
.and_then(|h| h.to_str().ok());
let user_id = validate_token(token).await?; let orders = sqlx::query!(
r#"
let orders = sqlx::query_as!( SELECT
Order, z.id as "id!",
r#"SELECT z.data_zamowienia as "data_zamowienia!",
id, z.suma_totalna as "suma_totalna!",
data_zamowienia as "data_zamowienia!", z.status,
suma_totalna, pz.ilosc as "ilosc!",
status pz.cena as "item_price!",
FROM zamowienia WHERE user_id = $1"#, k.tytul as "tytul!",
k.autor as "autor!"
FROM zamowienia z
JOIN pozycje_zamowienia pz ON z.id = pz.zamowienie_id
JOIN ksiazki k ON pz.book_id = k.id
WHERE z.user_id = $1
ORDER BY z.data_zamowienia DESC
"#,
user_id user_id
) )
.fetch_all(pool.get_ref()) .fetch_all(pool.get_ref())
.await .await
.map_err(|e| actix_web::error::ErrorInternalServerError(e))?; .map_err(|e| actix_web::error::ErrorInternalServerError(e))?;
Ok(HttpResponse::Ok().json(orders)) let mut grouped_orders = HashMap::new();
for record in orders {
let entry = grouped_orders.entry(record.id).or_insert(OrderWithItems {
id: record.id,
data_zamowienia: record.data_zamowienia,
suma_totalna: record.suma_totalna,
status: record.status,
items: Vec::new(),
});
entry.items.push(OrderItem {
tytul: record.tytul,
autor: record.autor,
ilosc: record.ilosc,
cena: record.item_price,
});
}
let result: Vec<OrderWithItems> = grouped_orders.into_values().collect();
Ok(HttpResponse::Ok().json(result))
} }
#[post("/api/checkout")] #[post("/api/checkout")]

View file

@ -250,3 +250,14 @@ footer a {
color: #0ff; color: #0ff;
text-shadow: 0 0 10px rgba(0, 255, 255, 0.5); text-shadow: 0 0 10px rgba(0, 255, 255, 0.5);
} }
.order-item {
background-color: #2a2a2a;
border-radius: 5px;
padding: 10px;
margin-bottom: 10px;
}
.order-item:last-child {
margin-bottom: 0;
}

View file

@ -18,13 +18,36 @@ document.addEventListener('DOMContentLoaded', async () => {
orders.forEach(order => { orders.forEach(order => {
const orderDate = new Date(order.data_zamowienia).toLocaleDateString(); const orderDate = new Date(order.data_zamowienia).toLocaleDateString();
const orderHTML = ` const itemsList = order.items.map(item => `
<div class="card dark-card mb-3"> <div class="card dark-card mb-2">
<div class="card-body"> <div class="card-body">
<h6 class="card-subtitle mb-2 text-muted">${item.tytul}</h6>
<p class="card-text">Autor: ${item.autor}</p>
<p class="card-text">Ilość: ${item.ilosc} × ${item.cena} PLN</p>
</div>
</div>
`).join('');
const orderHTML = `
<div class="mb-4">
<div class="card dark-card">
<div class="card-header">
<h5 class="card-title">Zamówienie #${order.id}</h5> <h5 class="card-title">Zamówienie #${order.id}</h5>
<p class="card-text">Data: ${orderDate}</p> <p class="card-text">Data: ${orderDate}</p>
<p class="card-text">Suma: ${order.suma_totalna} PLN</p> </div>
<p class="card-text">Status: ${order.status || 'Przyjęto do realizacji'}</p> <div class="card-body">
<h6 class="text-accent">Pozycje:</h6>
${itemsList}
<hr class="bg-secondary">
<div class="d-flex justify-content-between">
<p class="fw-bold">Suma całkowita:</p>
<p class="fw-bold">${order.suma_totalna} PLN</p>
</div>
<div class="d-flex justify-content-between">
<p>Status:</p>
<p class="text-accent">${order.status || 'Przyjęto do realizacji'}</p>
</div>
</div>
</div> </div>
</div> </div>
`; `;
@ -36,3 +59,4 @@ document.addEventListener('DOMContentLoaded', async () => {
alert('Nie udało się załadować historii zamówień'); alert('Nie udało się załadować historii zamówień');
} }
}); });

View file

@ -58,7 +58,7 @@
<button type="submit" class="btn btn-gothic w-100">ZALOGUJ SIĘ</button> <button type="submit" class="btn btn-gothic w-100">ZALOGUJ SIĘ</button>
</form> </form>
<div class="text-center mt-3"> <div class="text-center mt-3">
<a href="/register.html" class="text-danger">Nie masz konta? Zarejestruj się</a> Nie masz konta? <a href="/register.html" class="text-danger">Zarejestruj się</a>
</div> </div>
</div> </div>

View file

@ -64,8 +64,8 @@
</div> </div>
<button type="submit" class="btn btn-gothic w-100">ZAREJESTRUJ SIĘ</button> <button type="submit" class="btn btn-gothic w-100">ZAREJESTRUJ SIĘ</button>
</form> </form>
<div class="login-link"> <div class="text-center mt-3">
Masz już konto? <a href="/login.html" class="text-accent">Zaloguj się</a> Masz już konto? <a href="/login.html" class="text-danger">Zaloguj się</a>
</div> </div>
</div> </div>