feat: add overview of locations and users
This commit is contained in:
parent
a06f86dcaa
commit
6b35eda326
@ -6,7 +6,7 @@ use chrono::NaiveDate;
|
||||
use serde::Deserialize;
|
||||
use sqlx::PgPool;
|
||||
|
||||
use crate::models::User;
|
||||
use crate::models::{User, Role};
|
||||
|
||||
#[derive(Template)]
|
||||
#[template(path = "availabillity_new.html")]
|
||||
|
@ -5,7 +5,7 @@ use chrono::{NaiveDate, Utc};
|
||||
use serde::Deserialize;
|
||||
use sqlx::PgPool;
|
||||
|
||||
use crate::models::{Area, Availabillity, Event, Function, User};
|
||||
use crate::models::{Area, Availabillity, Event, Function, User, Role};
|
||||
|
||||
use super::{
|
||||
delete_availabillity::delete_availabillity,
|
||||
|
@ -5,7 +5,7 @@ use askama_actix::TemplateToResponse;
|
||||
use chrono::{NaiveDate, NaiveTime};
|
||||
use sqlx::PgPool;
|
||||
|
||||
use crate::{calendar::post_availabillity::AvailabillityForm, models::{Availabillity, User}};
|
||||
use crate::{calendar::post_availabillity::AvailabillityForm, models::{Availabillity, User, Role}};
|
||||
|
||||
use super::delete_availabillity::AvailabillityPath;
|
||||
|
||||
|
32
src/endpoints/location/mod.rs
Normal file
32
src/endpoints/location/mod.rs
Normal file
@ -0,0 +1,32 @@
|
||||
use actix_identity::Identity;
|
||||
use actix_web::{web, HttpResponse, Responder};
|
||||
use askama::Template;
|
||||
use askama_actix::TemplateToResponse;
|
||||
use sqlx::PgPool;
|
||||
|
||||
use crate::models::{Area, Location, Role, User};
|
||||
|
||||
#[derive(Template)]
|
||||
#[template(path = "locations.html")]
|
||||
pub struct LocationsTemplate {
|
||||
user: User,
|
||||
area: Area,
|
||||
locations: Vec<Location>
|
||||
}
|
||||
|
||||
#[actix_web::get("/locations")]
|
||||
pub async fn get(user: Identity, pool: web::Data<PgPool>) -> impl Responder {
|
||||
let current_user = User::read_by_id(pool.get_ref(), user.id().unwrap().parse().unwrap()).await.unwrap();
|
||||
|
||||
if current_user.role == Role::AreaManager {
|
||||
if let Ok(locations) = Location::read_by_area(pool.get_ref(), current_user.area_id).await {
|
||||
let area = Area::read_by_id(pool.get_ref(), current_user.area_id).await.unwrap();
|
||||
|
||||
let template = LocationsTemplate { user: current_user, area, locations};
|
||||
|
||||
return template.to_response()
|
||||
}
|
||||
}
|
||||
|
||||
return HttpResponse::BadRequest().body("Fehler beim Zugriff auf die Veranstaltungsorte!");
|
||||
}
|
10
src/endpoints/mod.rs
Normal file
10
src/endpoints/mod.rs
Normal file
@ -0,0 +1,10 @@
|
||||
use actix_web::web::ServiceConfig;
|
||||
|
||||
mod location;
|
||||
mod user;
|
||||
|
||||
pub fn init(cfg: &mut ServiceConfig) {
|
||||
cfg.service(location::get);
|
||||
|
||||
cfg.service(user::get);
|
||||
}
|
38
src/endpoints/user/mod.rs
Normal file
38
src/endpoints/user/mod.rs
Normal file
@ -0,0 +1,38 @@
|
||||
use actix_identity::Identity;
|
||||
use actix_web::{web, HttpResponse, Responder};
|
||||
use askama::Template;
|
||||
use askama_actix::TemplateToResponse;
|
||||
use sqlx::PgPool;
|
||||
|
||||
use crate::models::{Area, Role, User};
|
||||
|
||||
#[derive(Template)]
|
||||
#[template(path = "user/overview.html")]
|
||||
pub struct UsersTemplate {
|
||||
user: User,
|
||||
area: Option<Area>,
|
||||
users: Vec<User>
|
||||
}
|
||||
|
||||
#[actix_web::get("/users")]
|
||||
pub async fn get(user: Identity, pool: web::Data<PgPool>) -> impl Responder {
|
||||
let current_user = User::read_by_id(pool.get_ref(), user.id().unwrap().parse().unwrap()).await.unwrap();
|
||||
|
||||
if current_user.role == Role::AreaManager || current_user.role == Role::Admin {
|
||||
let mut area = None;
|
||||
let users;
|
||||
|
||||
if current_user.role == Role::AreaManager {
|
||||
area = Some(Area::read_by_id(pool.get_ref(), current_user.area_id).await.unwrap());
|
||||
users = User::read_all_by_area(pool.get_ref(), current_user.area_id).await.unwrap();
|
||||
} else {
|
||||
users = User::read_all(pool.get_ref()).await.unwrap();
|
||||
}
|
||||
|
||||
let template = UsersTemplate { user: current_user, area, users};
|
||||
|
||||
return template.to_response()
|
||||
}
|
||||
|
||||
return HttpResponse::BadRequest().body("Fehler beim Zugriff auf die Nutzerverwaltung!");
|
||||
}
|
@ -127,14 +127,92 @@ impl User {
|
||||
last_login: record.lastlogin,
|
||||
receive_notifications: record.receivenotifications,
|
||||
}),
|
||||
None => None
|
||||
None => None,
|
||||
};
|
||||
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
pub async fn read_all(pool: &PgPool) -> Option<Vec<User>> {
|
||||
todo!()
|
||||
pub async fn read_all(pool: &PgPool) -> anyhow::Result<Vec<User>> {
|
||||
let records = sqlx::query!(
|
||||
r#"
|
||||
SELECT id,
|
||||
name,
|
||||
email,
|
||||
password,
|
||||
salt,
|
||||
role AS "role: Role",
|
||||
function AS "function: Function",
|
||||
areaId,
|
||||
locked,
|
||||
lastLogin,
|
||||
receiveNotifications
|
||||
FROM user_;
|
||||
"#,
|
||||
)
|
||||
.fetch_all(pool)
|
||||
.await?;
|
||||
|
||||
let result = records
|
||||
.iter()
|
||||
.map(|record| User {
|
||||
id: record.id,
|
||||
name: record.name.clone(),
|
||||
email: record.email.clone(),
|
||||
password: record.password.clone(),
|
||||
salt: record.salt.clone(),
|
||||
role: record.role.clone(),
|
||||
function: record.function.clone(),
|
||||
area_id: record.areaid,
|
||||
locked: record.locked,
|
||||
last_login: record.lastlogin,
|
||||
receive_notifications: record.receivenotifications,
|
||||
})
|
||||
.collect();
|
||||
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
pub async fn read_all_by_area(pool: &PgPool, area_id: i32) -> anyhow::Result<Vec<User>> {
|
||||
let records = sqlx::query!(
|
||||
r#"
|
||||
SELECT id,
|
||||
name,
|
||||
email,
|
||||
password,
|
||||
salt,
|
||||
role AS "role: Role",
|
||||
function AS "function: Function",
|
||||
areaId,
|
||||
locked,
|
||||
lastLogin,
|
||||
receiveNotifications
|
||||
FROM user_
|
||||
WHERE areaId = $1;
|
||||
"#,
|
||||
area_id
|
||||
)
|
||||
.fetch_all(pool)
|
||||
.await?;
|
||||
|
||||
let result = records
|
||||
.iter()
|
||||
.map(|record| User {
|
||||
id: record.id,
|
||||
name: record.name.clone(),
|
||||
email: record.email.clone(),
|
||||
password: record.password.clone(),
|
||||
salt: record.salt.clone(),
|
||||
role: record.role.clone(),
|
||||
function: record.function.clone(),
|
||||
area_id: record.areaid,
|
||||
locked: record.locked,
|
||||
last_login: record.lastlogin,
|
||||
receive_notifications: record.receivenotifications,
|
||||
})
|
||||
.collect();
|
||||
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
pub async fn update(pool: &PgPool, id: i32, updated_user: User) -> Option<User> {
|
||||
|
34
templates/locations.html
Normal file
34
templates/locations.html
Normal file
@ -0,0 +1,34 @@
|
||||
{% extends "nav.html" %}
|
||||
|
||||
{% block content %}
|
||||
<section class="section">
|
||||
<div class="container">
|
||||
<div class="level">
|
||||
<div class="level-left">
|
||||
<h3 class="title is-3">
|
||||
Veranstaltungsorte im Bereich {{ area.name }}
|
||||
</h3>
|
||||
</div>
|
||||
<div class="level-right">
|
||||
<a class="button" href="/event/new">Neues Event für diesen Tag</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% if locations.len() == 0 %}
|
||||
<div class="box">
|
||||
<h5 class="title is-5">keine Orte vorhanden</h5>
|
||||
</div>
|
||||
{% else %}
|
||||
{% for location in locations %}
|
||||
<div class="box">
|
||||
<h5 class="title is-5">{{ location.name }}</h5>
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
</div>
|
||||
</section>
|
||||
</section>
|
||||
|
||||
<script>
|
||||
</script>
|
||||
{% endblock %}
|
@ -21,10 +21,22 @@
|
||||
</a>
|
||||
|
||||
{% match user.role %}
|
||||
{% when AreaManager %}
|
||||
{% when Role::Staff %}
|
||||
{% when Role::AreaManager %}
|
||||
<a class="navbar-item">
|
||||
Planung
|
||||
</a>
|
||||
<a href="/locations" class="navbar-item">
|
||||
Veranstaltungsorte
|
||||
</a>
|
||||
<a href="/users" class="navbar-item">
|
||||
Nutzerverwaltung
|
||||
</a>
|
||||
{% when Role::Admin %}
|
||||
<a href="/users" class="navbar-item">
|
||||
Nutzerverwaltung
|
||||
</a>
|
||||
|
||||
{% endmatch %}
|
||||
</div>
|
||||
|
||||
|
34
templates/user/overview.html
Normal file
34
templates/user/overview.html
Normal file
@ -0,0 +1,34 @@
|
||||
{% extends "nav.html" %}
|
||||
|
||||
{% block content %}
|
||||
<section class="section">
|
||||
<div class="container">
|
||||
<div class="level">
|
||||
<div class="level-left">
|
||||
<h3 class="title is-3">
|
||||
Nutzer
|
||||
</h3>
|
||||
</div>
|
||||
<div class="level-right">
|
||||
<a class="button" href="/users/new">Neuen Nutzer anlegen</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% if users.len() == 0 %}
|
||||
<div class="box">
|
||||
<h5 class="title is-5">keine Orte vorhanden</h5>
|
||||
</div>
|
||||
{% else %}
|
||||
{% for u in users %}
|
||||
<div class="box">
|
||||
<h5 class="title is-5">{{ u.email }}</h5>
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
</div>
|
||||
</section>
|
||||
</section>
|
||||
|
||||
<script>
|
||||
</script>
|
||||
{% endblock %}
|
Loading…
x
Reference in New Issue
Block a user