feat: create and view edit users
This commit is contained in:
parent
6b35eda326
commit
e107687f71
@ -1,4 +1,4 @@
|
||||
CREATE TYPE role AS ENUM ('staff', 'area manager', 'admin');
|
||||
CREATE TYPE role AS ENUM ('staff', 'areamanager', 'admin');
|
||||
CREATE TYPE function AS ENUM ('posten', 'wachhabender');
|
||||
|
||||
CREATE TABLE area
|
||||
|
@ -33,10 +33,10 @@ async fn route(
|
||||
|
||||
let result = User::create(
|
||||
pool.get_ref(),
|
||||
form.name,
|
||||
form.email,
|
||||
hash,
|
||||
salt,
|
||||
&form.name,
|
||||
&form.email,
|
||||
&hash,
|
||||
&salt,
|
||||
role,
|
||||
function,
|
||||
form.area_id,
|
||||
|
@ -1,10 +1,19 @@
|
||||
use actix_web::web::ServiceConfig;
|
||||
use serde::Deserialize;
|
||||
|
||||
mod location;
|
||||
mod user;
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct IdPath {
|
||||
pub id: i32
|
||||
}
|
||||
|
||||
pub fn init(cfg: &mut ServiceConfig) {
|
||||
cfg.service(location::get);
|
||||
|
||||
cfg.service(user::get);
|
||||
cfg.service(user::get_overview::get_overview);
|
||||
cfg.service(user::get_new::get_new);
|
||||
cfg.service(user::post_new::post_new);
|
||||
cfg.service(user::get_edit::get_edit);
|
||||
}
|
||||
|
37
src/endpoints/user/get_edit.rs
Normal file
37
src/endpoints/user/get_edit.rs
Normal file
@ -0,0 +1,37 @@
|
||||
use actix_identity::Identity;
|
||||
use actix_web::{web, HttpResponse, Responder};
|
||||
use askama::Template;
|
||||
use askama_actix::TemplateToResponse;
|
||||
use sqlx::PgPool;
|
||||
|
||||
use crate::{endpoints::IdPath, models::{Area, Role, User}};
|
||||
|
||||
#[derive(Template)]
|
||||
#[template(path = "user/edit.html")]
|
||||
pub struct EditUserTemplate {
|
||||
user: User,
|
||||
areas: Option<Vec<Area>>,
|
||||
email: String,
|
||||
name: String,
|
||||
role: u8,
|
||||
function: u8,
|
||||
area_id: i32
|
||||
}
|
||||
|
||||
#[actix_web::get("/users/edit/{id}")]
|
||||
pub async fn get_edit(user: Identity, pool: web::Data<PgPool>, path: web::Path<IdPath>) -> impl Responder {
|
||||
let current_user = User::read_by_id(pool.get_ref(), user.id().unwrap().parse().unwrap()).await.unwrap();
|
||||
let mut areas = None;
|
||||
|
||||
if current_user.role == Role::Admin {
|
||||
areas = Some(Area::read_all(pool.get_ref()).await.unwrap());
|
||||
}
|
||||
|
||||
if let Ok(user_in_db) = User::read_by_id(pool.get_ref(), path.id).await {
|
||||
let template = EditUserTemplate { user: current_user, areas, email: user_in_db.email, name: user_in_db.name, role: user_in_db.role as u8, function: user_in_db.function as u8, area_id: user_in_db.area_id };
|
||||
|
||||
return template.to_response();
|
||||
}
|
||||
|
||||
HttpResponse::BadRequest().body("Fehler beim Bearbeiten des Nutzers")
|
||||
}
|
28
src/endpoints/user/get_new.rs
Normal file
28
src/endpoints/user/get_new.rs
Normal file
@ -0,0 +1,28 @@
|
||||
use actix_identity::Identity;
|
||||
use actix_web::{web, Responder};
|
||||
use askama::Template;
|
||||
use askama_actix::TemplateToResponse;
|
||||
use sqlx::PgPool;
|
||||
|
||||
use crate::models::{Area, Role, User};
|
||||
|
||||
#[derive(Template)]
|
||||
#[template(path = "user/new.html")]
|
||||
pub struct NewUserTemplate {
|
||||
user: User,
|
||||
areas: Option<Vec<Area>>
|
||||
}
|
||||
|
||||
#[actix_web::get("/users/new")]
|
||||
pub async fn get_new(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();
|
||||
let mut areas: Option<Vec<Area>> = None;
|
||||
|
||||
if current_user.role == Role::Admin {
|
||||
areas = Some(Area::read_all(pool.get_ref()).await.unwrap())
|
||||
}
|
||||
|
||||
let template = NewUserTemplate { user: current_user, areas };
|
||||
|
||||
template.to_response()
|
||||
}
|
49
src/endpoints/user/get_overview.rs
Normal file
49
src/endpoints/user/get_overview.rs
Normal file
@ -0,0 +1,49 @@
|
||||
use crate::models::{Area, Role, User, Function};
|
||||
use actix_identity::Identity;
|
||||
use actix_web::{web, HttpResponse, Responder};
|
||||
use askama::Template;
|
||||
use askama_actix::TemplateToResponse;
|
||||
use sqlx::PgPool;
|
||||
|
||||
#[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_overview(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_including_area(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!");
|
||||
}
|
@ -1,38 +1,5 @@
|
||||
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!");
|
||||
}
|
||||
pub mod get_overview;
|
||||
pub mod get_new;
|
||||
pub mod post_new;
|
||||
pub mod get_edit;
|
||||
pub mod put_edit;
|
||||
|
41
src/endpoints/user/post_new.rs
Normal file
41
src/endpoints/user/post_new.rs
Normal file
@ -0,0 +1,41 @@
|
||||
use actix_identity::Identity;
|
||||
use actix_web::{http::header::LOCATION, web, HttpResponse, Responder};
|
||||
use serde::Deserialize;
|
||||
use sqlx::PgPool;
|
||||
|
||||
use crate::{auth::utils::generate_salt_and_hash_plain_password, models::{Function, Role, User}};
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct NewUserForm {
|
||||
email: String,
|
||||
name: String,
|
||||
password: String,
|
||||
role: u8,
|
||||
function: u8,
|
||||
area: Option<i32>
|
||||
}
|
||||
|
||||
#[actix_web::post("/users/new")]
|
||||
pub async fn post_new(user: Identity, pool: web::Data<PgPool>, form: web::Form<NewUserForm>) -> impl Responder {
|
||||
let current_user = User::read_by_id(pool.get_ref(), user.id().unwrap().parse().unwrap()).await.unwrap();
|
||||
let mut area_id = current_user.area_id;
|
||||
|
||||
if current_user.role == Role::Admin {
|
||||
if let Some(id) = form.area {
|
||||
area_id = id;
|
||||
}
|
||||
}
|
||||
|
||||
if let Ok((hash, salt)) = generate_salt_and_hash_plain_password(&form.password) {
|
||||
if let Ok(role) = Role::try_from(form.role) {
|
||||
if let Ok(function) = Function::try_from(form.function) {
|
||||
match User::create(pool.get_ref(), &form.name, &form.email, &hash, &salt, role, function, area_id).await {
|
||||
Ok(_) => return HttpResponse::Found().insert_header((LOCATION, "/users")).finish(),
|
||||
Err(err) => println!("{}", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return HttpResponse::BadRequest().body("Fehler beim Erstellen des Nutzers");
|
||||
}
|
0
src/endpoints/user/put_edit.rs
Normal file
0
src/endpoints/user/put_edit.rs
Normal file
@ -1,5 +1,6 @@
|
||||
use sqlx::{query, query_as, PgPool};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Area {
|
||||
pub id: i32,
|
||||
pub name: String
|
||||
|
@ -102,6 +102,7 @@ impl Availabillity {
|
||||
role: r.role.clone(),
|
||||
function: r.function.clone(),
|
||||
area_id: r.areaid,
|
||||
area: None,
|
||||
locked: r.locked,
|
||||
last_login: r.lastlogin,
|
||||
receive_notifications: r.receivenotifications,
|
||||
|
@ -1,7 +1,7 @@
|
||||
use chrono::{DateTime, Utc};
|
||||
use sqlx::PgPool;
|
||||
|
||||
use super::{Function, Role};
|
||||
use super::{Area, Function, Role};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct User {
|
||||
@ -13,6 +13,7 @@ pub struct User {
|
||||
pub role: Role,
|
||||
pub function: Function,
|
||||
pub area_id: i32,
|
||||
pub area: Option<Area>,
|
||||
pub locked: bool,
|
||||
pub last_login: Option<DateTime<Utc>>,
|
||||
pub receive_notifications: bool,
|
||||
@ -21,10 +22,10 @@ pub struct User {
|
||||
impl User {
|
||||
pub async fn create(
|
||||
pool: &PgPool,
|
||||
name: String,
|
||||
email: String,
|
||||
password: String,
|
||||
salt: String,
|
||||
name: &str,
|
||||
email: &str,
|
||||
password: &str,
|
||||
salt: &str,
|
||||
role: Role,
|
||||
function: Function,
|
||||
area_id: i32,
|
||||
@ -83,6 +84,7 @@ impl User {
|
||||
role: record.role,
|
||||
function: record.function,
|
||||
area_id: record.areaid,
|
||||
area: None,
|
||||
locked: record.locked,
|
||||
last_login: record.lastlogin,
|
||||
receive_notifications: record.receivenotifications,
|
||||
@ -123,6 +125,7 @@ impl User {
|
||||
role: record.role,
|
||||
function: record.function,
|
||||
area_id: record.areaid,
|
||||
area: None,
|
||||
locked: record.locked,
|
||||
last_login: record.lastlogin,
|
||||
receive_notifications: record.receivenotifications,
|
||||
@ -164,6 +167,7 @@ impl User {
|
||||
role: record.role.clone(),
|
||||
function: record.function.clone(),
|
||||
area_id: record.areaid,
|
||||
area: None,
|
||||
locked: record.locked,
|
||||
last_login: record.lastlogin,
|
||||
receive_notifications: record.receivenotifications,
|
||||
@ -173,6 +177,54 @@ impl User {
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
pub async fn read_all_including_area(pool: &PgPool) -> anyhow::Result<Vec<User>> {
|
||||
let records = sqlx::query!(
|
||||
r#"
|
||||
SELECT
|
||||
user_.id AS userId,
|
||||
user_.name,
|
||||
user_.email,
|
||||
user_.password,
|
||||
user_.salt,
|
||||
user_.role AS "role: Role",
|
||||
user_.function AS "function: Function",
|
||||
user_.areaId,
|
||||
user_.locked,
|
||||
user_.lastLogin,
|
||||
user_.receiveNotifications,
|
||||
area.id,
|
||||
area.name AS areaName
|
||||
FROM user_
|
||||
JOIN area ON user_.areaId = area.id
|
||||
"#
|
||||
)
|
||||
.fetch_all(pool)
|
||||
.await?;
|
||||
|
||||
let results = records
|
||||
.iter()
|
||||
.map(|record| User {
|
||||
id: record.userid,
|
||||
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,
|
||||
area: Some(Area {
|
||||
id: record.areaid,
|
||||
name: record.areaname.clone(),
|
||||
}),
|
||||
locked: record.locked,
|
||||
last_login: record.lastlogin,
|
||||
receive_notifications: record.receivenotifications,
|
||||
})
|
||||
.collect();
|
||||
|
||||
Ok(results)
|
||||
}
|
||||
|
||||
pub async fn read_all_by_area(pool: &PgPool, area_id: i32) -> anyhow::Result<Vec<User>> {
|
||||
let records = sqlx::query!(
|
||||
r#"
|
||||
@ -206,6 +258,7 @@ impl User {
|
||||
role: record.role.clone(),
|
||||
function: record.function.clone(),
|
||||
area_id: record.areaid,
|
||||
area: None,
|
||||
locked: record.locked,
|
||||
last_login: record.lastlogin,
|
||||
receive_notifications: record.receivenotifications,
|
||||
@ -215,11 +268,11 @@ impl User {
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
pub async fn update(pool: &PgPool, id: i32, updated_user: User) -> Option<User> {
|
||||
todo!()
|
||||
}
|
||||
// pub async fn update(pool: &PgPool, id: i32, updated_user: User) -> Option<User> {
|
||||
// todo!()
|
||||
// }
|
||||
|
||||
pub async fn delete(pool: &PgPool, id: i32) -> anyhow::Result<bool> {
|
||||
todo!()
|
||||
}
|
||||
// pub async fn delete(pool: &PgPool, id: i32) -> anyhow::Result<bool> {
|
||||
// todo!()
|
||||
// }
|
||||
}
|
||||
|
126
templates/user/edit.html
Normal file
126
templates/user/edit.html
Normal file
@ -0,0 +1,126 @@
|
||||
{% extends "nav.html" %}
|
||||
|
||||
{% block content %}
|
||||
<section class="section">
|
||||
<div class="container">
|
||||
<form method="post" action="/users/new">
|
||||
<h1 class="title">Nutzer {{ name }} bearbeiten</h1>
|
||||
|
||||
<div class="field is-horizontal">
|
||||
<div class="field-label">
|
||||
<label class="label">E-Mail</label>
|
||||
</div>
|
||||
<div class="field-body">
|
||||
<div class="field">
|
||||
<div class="control">
|
||||
<input class="input" type="text" name="email" placeholder="max.mustermann@brasiwa-leipzig.de" value="{{ email }}"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="field is-horizontal">
|
||||
<div class="field-label">
|
||||
<label class="label">Name</label>
|
||||
</div>
|
||||
<div class="field-body">
|
||||
<div class="field">
|
||||
<div class="control">
|
||||
<input class="input" type="text" name="name" placeholder="Max Mustermann" value="{{ name }}"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="field is-horizontal">
|
||||
<div class="field-label">
|
||||
<label class="label">Password</label>
|
||||
</div>
|
||||
<div class="field-body">
|
||||
<div class="field">
|
||||
<div class="control">
|
||||
<input class="input" type="password" name="password" placeholder="**********"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="field is-horizontal">
|
||||
<div class="field-label">
|
||||
<label class="label">Rolle</label>
|
||||
</div>
|
||||
<div class="field-body">
|
||||
<div class="field is-narrow">
|
||||
<div class="control">
|
||||
<div class="select is-fullwidth">
|
||||
<select name="role">
|
||||
<option value="1" {% if role == 1%}selected{% endif %}>Personal</option>
|
||||
<option value="10" {% if role == 10%}selected{% endif %}>Bereichsleiter</option>
|
||||
<option value="100" {% if role == 100%}selected{% endif %}>Admin</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="field is-horizontal">
|
||||
<div class="field-label">
|
||||
<label class="label">Funktion</label>
|
||||
</div>
|
||||
<div class="field-body">
|
||||
<div class="field is-narrow">
|
||||
<div class="control">
|
||||
<div class="select is-fullwidth">
|
||||
<select name="function">
|
||||
<option value="1" {% if function == 1%}selected{% endif %}>Posten</option>
|
||||
<option value="10" {% if function == 10%}selected{% endif %}>Wachhabender</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% if user.role == Role::Admin %}
|
||||
<div class="field is-horizontal">
|
||||
<div class="field-label">
|
||||
<label class="label">Bereich</label>
|
||||
</div>
|
||||
<div class="field-body">
|
||||
<div class="field is-narrow">
|
||||
<div class="control">
|
||||
<div class="select is-fullwidth">
|
||||
<select name="area">
|
||||
{% for area in areas.as_ref().unwrap() %}
|
||||
<option value="{{ area.id }}" {% if area.id == area_id%}selected{% endif %}>{{ area.name }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<div class="field is-horizontal">
|
||||
<div class="field-label"></div>
|
||||
<div class="field-body">
|
||||
<div class="field is-grouped">
|
||||
<div class="control">
|
||||
<input class="button is-link" type="submit" value="Erstellen">
|
||||
</div>
|
||||
<div class="control">
|
||||
<a class="button is-link is-light" href="/users">Zurück</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</form>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<script>
|
||||
</script>
|
||||
{% endblock %}
|
126
templates/user/new.html
Normal file
126
templates/user/new.html
Normal file
@ -0,0 +1,126 @@
|
||||
{% extends "nav.html" %}
|
||||
|
||||
{% block content %}
|
||||
<section class="section">
|
||||
<div class="container">
|
||||
<form method="post" action="/users/new">
|
||||
<h1 class="title">Neuen Nutzer anlegen</h1>
|
||||
|
||||
<div class="field is-horizontal">
|
||||
<div class="field-label">
|
||||
<label class="label">E-Mail</label>
|
||||
</div>
|
||||
<div class="field-body">
|
||||
<div class="field">
|
||||
<div class="control">
|
||||
<input class="input" type="text" name="email" placeholder="max.mustermann@brasiwa-leipzig.de"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="field is-horizontal">
|
||||
<div class="field-label">
|
||||
<label class="label">Name</label>
|
||||
</div>
|
||||
<div class="field-body">
|
||||
<div class="field">
|
||||
<div class="control">
|
||||
<input class="input" type="text" name="name" placeholder="Max Mustermann"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="field is-horizontal">
|
||||
<div class="field-label">
|
||||
<label class="label">Password</label>
|
||||
</div>
|
||||
<div class="field-body">
|
||||
<div class="field">
|
||||
<div class="control">
|
||||
<input class="input" type="password" name="password" placeholder="**********"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="field is-horizontal">
|
||||
<div class="field-label">
|
||||
<label class="label">Rolle</label>
|
||||
</div>
|
||||
<div class="field-body">
|
||||
<div class="field is-narrow">
|
||||
<div class="control">
|
||||
<div class="select is-fullwidth">
|
||||
<select name="role">
|
||||
<option value="1">Personal</option>
|
||||
<option value="10">Bereichsleiter</option>
|
||||
<option value="100">Admin</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="field is-horizontal">
|
||||
<div class="field-label">
|
||||
<label class="label">Funktion</label>
|
||||
</div>
|
||||
<div class="field-body">
|
||||
<div class="field is-narrow">
|
||||
<div class="control">
|
||||
<div class="select is-fullwidth">
|
||||
<select name="function">
|
||||
<option value="1">Posten</option>
|
||||
<option value="10">Wachhabender</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% if user.role == Role::Admin %}
|
||||
<div class="field is-horizontal">
|
||||
<div class="field-label">
|
||||
<label class="label">Bereich</label>
|
||||
</div>
|
||||
<div class="field-body">
|
||||
<div class="field is-narrow">
|
||||
<div class="control">
|
||||
<div class="select is-fullwidth">
|
||||
<select name="area">
|
||||
{% for area in areas.as_ref().unwrap() %}
|
||||
<option value="{{ area.id }}">{{ area.name }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<div class="field is-horizontal">
|
||||
<div class="field-label"></div>
|
||||
<div class="field-body">
|
||||
<div class="field is-grouped">
|
||||
<div class="control">
|
||||
<input class="button is-link" type="submit" value="Erstellen">
|
||||
</div>
|
||||
<div class="control">
|
||||
<a class="button is-link is-light" href="/users">Zurück</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</form>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<script>
|
||||
</script>
|
||||
{% endblock %}
|
@ -6,7 +6,7 @@
|
||||
<div class="level">
|
||||
<div class="level-left">
|
||||
<h3 class="title is-3">
|
||||
Nutzer
|
||||
Nutzer {% if user.role == Role::AreaManager %}für Bereich {{ area.as_ref().unwrap().name }}{% endif %}
|
||||
</h3>
|
||||
</div>
|
||||
<div class="level-right">
|
||||
@ -16,14 +16,68 @@
|
||||
|
||||
{% if users.len() == 0 %}
|
||||
<div class="box">
|
||||
<h5 class="title is-5">keine Orte vorhanden</h5>
|
||||
<h5 class="title is-5">keine Nutzer vorhanden</h5>
|
||||
</div>
|
||||
{% else %}
|
||||
{% for u in users %}
|
||||
<div class="box">
|
||||
<h5 class="title is-5">{{ u.email }}</h5>
|
||||
<table class="table is-fullwidth">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>E-Mail</th>
|
||||
<th>Name</th>
|
||||
<th>Rolle</th>
|
||||
<th>Funktion</th>
|
||||
{% if user.role == Role::Admin %}
|
||||
<th>Bereich</th>
|
||||
{% endif %}
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for u in users %}
|
||||
<tr>
|
||||
<td>
|
||||
{{ u.email }}
|
||||
</td>
|
||||
<td>
|
||||
{{ u.name }}
|
||||
</td>
|
||||
<td>
|
||||
{% match u.role %}
|
||||
{% when Role::Staff %}
|
||||
<span class="tag is-info is-light">Nutzer</span>
|
||||
{% when Role::AreaManager %}
|
||||
<span class="tag is-info is-light">Bereichsleiter</span>
|
||||
{% when Role::Admin %}
|
||||
<span class="tag is-info">Admin</span>
|
||||
{% else %}
|
||||
{% endmatch %}
|
||||
</td>
|
||||
<td>
|
||||
{% match u.function %}
|
||||
{% when Function::Posten %}
|
||||
<span class="tag is-info is-light">Posten</span>
|
||||
{% when Function::Wachhabender %}
|
||||
<span class="tag is-info">Wachhabender</span>
|
||||
{% else %}
|
||||
{% endmatch %}
|
||||
</td>
|
||||
{% if user.role == Role::Admin %}
|
||||
<td>
|
||||
{{ u.area.as_ref().unwrap().name }}
|
||||
</td>
|
||||
{% endif %}
|
||||
<td>
|
||||
<div class="buttons is-right">
|
||||
<a class="button is-link" href="/users/edit/{{ u.id }}">Bearbeiten</a>
|
||||
<button class="button is-danger" name="delete-availabillity">Löschen</button>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</section>
|
||||
|
Loading…
x
Reference in New Issue
Block a user