Initial
This commit is contained in:
		
						commit
						d23055a0bf
					
				
							
								
								
									
										4
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,4 @@
 | 
				
			||||||
 | 
					/target
 | 
				
			||||||
 | 
					package-lock.json
 | 
				
			||||||
 | 
					node_modules/
 | 
				
			||||||
 | 
					build/
 | 
				
			||||||
							
								
								
									
										1324
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						
									
										1324
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										17
									
								
								Cargo.toml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								Cargo.toml
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,17 @@
 | 
				
			||||||
 | 
					[package]
 | 
				
			||||||
 | 
					name = "persmgr-gui"
 | 
				
			||||||
 | 
					version = "0.1.0"
 | 
				
			||||||
 | 
					edition = "2024"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[dependencies]
 | 
				
			||||||
 | 
					anyhow = "1.0.99"
 | 
				
			||||||
 | 
					askama = "0.14.0"
 | 
				
			||||||
 | 
					axum = "0.8.4"
 | 
				
			||||||
 | 
					serde = { version = "1.0.219", features = ["derive"] }
 | 
				
			||||||
 | 
					serde_json = "1.0.143"
 | 
				
			||||||
 | 
					tokio = { version = "1.47.1", features = ["full"] }
 | 
				
			||||||
 | 
					toml = "0.9.5"
 | 
				
			||||||
 | 
					tower = { version = "0.5.2", features = ["full"] }
 | 
				
			||||||
 | 
					tower-http = { version = "0.6.6", features = ["full"] }
 | 
				
			||||||
 | 
					tracing = "0.1.41"
 | 
				
			||||||
 | 
					tracing-subscriber = "0.3.20"
 | 
				
			||||||
							
								
								
									
										14
									
								
								README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								README.md
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,14 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Dashboard
 | 
				
			||||||
 | 
					Roster
 | 
				
			||||||
 | 
					Management (with the right permissions only)
 | 
				
			||||||
 | 
					Documents
 | 
				
			||||||
 | 
					User (something shorter than personal file)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(user icon) (dropdown)
 | 
				
			||||||
 | 
					 - Account
 | 
				
			||||||
 | 
					 - Preferences
 | 
				
			||||||
 | 
					 - Logout
 | 
				
			||||||
							
								
								
									
										19
									
								
								persmgr-gui-rs/Cargo.toml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								persmgr-gui-rs/Cargo.toml
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,19 @@
 | 
				
			||||||
 | 
					[package]
 | 
				
			||||||
 | 
					name = "persmgr-gui"
 | 
				
			||||||
 | 
					version = "0.1.0"
 | 
				
			||||||
 | 
					edition = "2024"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[dependencies]
 | 
				
			||||||
 | 
					anyhow = "1.0.99"
 | 
				
			||||||
 | 
					image = "0.25.7"
 | 
				
			||||||
 | 
					reqwest = { version = "0.12.23", features = ["json", "blocking"] }
 | 
				
			||||||
 | 
					serde = { version = "1.0.219", features = ["derive"] }
 | 
				
			||||||
 | 
					serde_json = "1.0.143"
 | 
				
			||||||
 | 
					slint = { version = "1.12.1", features = ["gettext", "log", "serde", "image-default-formats"] }
 | 
				
			||||||
 | 
					tokio = "1.47.1"
 | 
				
			||||||
 | 
					toml = "0.9.5"
 | 
				
			||||||
 | 
					tracing = "0.1.41"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[build-dependencies]
 | 
				
			||||||
 | 
					slint-build = "1.12.1"
 | 
				
			||||||
							
								
								
									
										3
									
								
								persmgr-gui-rs/build.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								persmgr-gui-rs/build.rs
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,3 @@
 | 
				
			||||||
 | 
					fn main() {
 | 
				
			||||||
 | 
					    slint_build::compile("ui/main.slint").unwrap();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										12
									
								
								persmgr-gui-rs/src/main.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								persmgr-gui-rs/src/main.rs
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,12 @@
 | 
				
			||||||
 | 
					slint::include_modules!();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fn main() {
 | 
				
			||||||
 | 
					    let app = MainWindow::new().unwrap();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // connect callback
 | 
				
			||||||
 | 
					    app.on_clicked(|| {
 | 
				
			||||||
 | 
					        println!("Button was clicked owo");
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    app.run().unwrap();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										24
									
								
								persmgr-gui-rs/ui/main.slint
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								persmgr-gui-rs/ui/main.slint
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,24 @@
 | 
				
			||||||
 | 
					import { Button } from "std-widgets.slint";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export component MainWindow inherits Window {
 | 
				
			||||||
 | 
					    width: 400px;
 | 
				
			||||||
 | 
					    height: 300px;
 | 
				
			||||||
 | 
					    title: "My Slint App :3";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    VerticalLayout {
 | 
				
			||||||
 | 
					        Text {
 | 
				
			||||||
 | 
					            text: "Hello nya~ from Slint!";
 | 
				
			||||||
 | 
					            horizontal-alignment: center;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Button {
 | 
				
			||||||
 | 
					            text: "Click me!";
 | 
				
			||||||
 | 
					            clicked => {
 | 
				
			||||||
 | 
					                root.clicked();
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    callback clicked();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										54
									
								
								persmgr-gui-rs/ui/top_nav.slint
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								persmgr-gui-rs/ui/top_nav.slint
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,54 @@
 | 
				
			||||||
 | 
					import { Button } from "std-widgets.slint";
 | 
				
			||||||
 | 
					export component TopNavBar inherits HorizontalLayout {
 | 
				
			||||||
 | 
					    height: 50px;
 | 
				
			||||||
 | 
					    spacing: 16px;
 | 
				
			||||||
 | 
					    padding-left: 16px;
 | 
				
			||||||
 | 
					    padding-right: 16px;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Permission flag for Management tab
 | 
				
			||||||
 | 
					    in property <bool> is_officer: false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // callbacks for tabs
 | 
				
			||||||
 | 
					    callback dashboard_clicked();
 | 
				
			||||||
 | 
					    callback roster_clicked();
 | 
				
			||||||
 | 
					    callback management_clicked();
 | 
				
			||||||
 | 
					    callback documents_clicked();
 | 
				
			||||||
 | 
					    callback profile_clicked();
 | 
				
			||||||
 | 
					    callback user_account_clicked();
 | 
				
			||||||
 | 
					    callback user_preferences_clicked();
 | 
				
			||||||
 | 
					    callback user_logout_clicked();
 | 
				
			||||||
 | 
					    Button {
 | 
				
			||||||
 | 
					        text: "Dashboard";
 | 
				
			||||||
 | 
					        clicked() => {
 | 
				
			||||||
 | 
					            root.dashboard_clicked();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Button {
 | 
				
			||||||
 | 
					        text: "Roster";
 | 
				
			||||||
 | 
					        clicked() => {
 | 
				
			||||||
 | 
					            root.roster_clicked();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Button {
 | 
				
			||||||
 | 
					        text: "Management";
 | 
				
			||||||
 | 
					        clicked() => {
 | 
				
			||||||
 | 
					            root.management_clicked();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Button {
 | 
				
			||||||
 | 
					        text: "Documents";
 | 
				
			||||||
 | 
					        clicked() => {
 | 
				
			||||||
 | 
					            root.documents_clicked();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Button {
 | 
				
			||||||
 | 
					        text: "Your file";
 | 
				
			||||||
 | 
					        clicked() => {
 | 
				
			||||||
 | 
					            root.dashboard_clicked();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										38
									
								
								res/css/global.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								res/css/global.css
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,38 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					:root {
 | 
				
			||||||
 | 
					    --bg-color-ll: #535353;
 | 
				
			||||||
 | 
					    --bg-color-l: #434343;
 | 
				
			||||||
 | 
					    --bg-color: #323232;
 | 
				
			||||||
 | 
					    --bg-color-d: #292929;
 | 
				
			||||||
 | 
					    --bg-color-dd: #212121;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					body {
 | 
				
			||||||
 | 
					    background: var(--bg-color);
 | 
				
			||||||
 | 
					    font-family: Arial, Helvetica, sans-serif;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#topnav {
 | 
				
			||||||
 | 
					    width: 100%;
 | 
				
			||||||
 | 
					    height: 10%;
 | 
				
			||||||
 | 
					    background: var(--bg-color-l);
 | 
				
			||||||
 | 
					    display: flex;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.topnav_button {
 | 
				
			||||||
 | 
					    padding: 1rem 3rem;
 | 
				
			||||||
 | 
					    margin: 3px 10px;
 | 
				
			||||||
 | 
					    background: var(--bg-color-ll);
 | 
				
			||||||
 | 
					    border: 2px solid var(--bg-color);
 | 
				
			||||||
 | 
					    border-radius: 10px;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.topnav_button a {
 | 
				
			||||||
 | 
					    text_decoration: none;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.topnav_button:hover {
 | 
				
			||||||
 | 
					    cursor: pointer
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										
											BIN
										
									
								
								res/favicon.ico
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								res/favicon.ico
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 274 KiB  | 
							
								
								
									
										11
									
								
								src/api/mod.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								src/api/mod.rs
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,11 @@
 | 
				
			||||||
 | 
					use axum::{Router, http::StatusCode, routing::get};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					async fn root() -> (StatusCode, &'static str) {
 | 
				
			||||||
 | 
					    (StatusCode::OK, "We Good twin :3c")
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub fn register_routes() -> Router {
 | 
				
			||||||
 | 
					    let router = Router::new().route("/", get(root));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Router::new().nest("/api", router)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										30
									
								
								src/main.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								src/main.rs
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,30 @@
 | 
				
			||||||
 | 
					use axum::Router;
 | 
				
			||||||
 | 
					use tower::ServiceBuilder;
 | 
				
			||||||
 | 
					use tower_http::{services::ServeDir, trace::TraceLayer};
 | 
				
			||||||
 | 
					use tracing::{info, level_filters::LevelFilter};
 | 
				
			||||||
 | 
					use tracing_subscriber::FmtSubscriber;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					mod api;
 | 
				
			||||||
 | 
					mod pages;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[tokio::main]
 | 
				
			||||||
 | 
					async fn main() {
 | 
				
			||||||
 | 
					    let sub = FmtSubscriber::builder()
 | 
				
			||||||
 | 
					        .with_max_level(LevelFilter::DEBUG)
 | 
				
			||||||
 | 
					        .finish();
 | 
				
			||||||
 | 
					    tracing::subscriber::set_global_default(sub).unwrap();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    info!("Server starting");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let app = Router::new()
 | 
				
			||||||
 | 
					        .merge(pages::register_routes())
 | 
				
			||||||
 | 
					        .merge(api::register_routes())
 | 
				
			||||||
 | 
					        .fallback_service(ServiceBuilder::new().service(ServeDir::new("res")))
 | 
				
			||||||
 | 
					        .layer(ServiceBuilder::new().layer(TraceLayer::new_for_http()));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let laddr = "0.0.0.0:8080";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let sock = tokio::net::TcpListener::bind(laddr).await.unwrap();
 | 
				
			||||||
 | 
					    info!("Listening on http://{laddr}");
 | 
				
			||||||
 | 
					    axum::serve(sock, app).await.unwrap();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										12
									
								
								src/pages/index.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								src/pages/index.rs
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,12 @@
 | 
				
			||||||
 | 
					use askama::Template;
 | 
				
			||||||
 | 
					use axum::{http::StatusCode, response::Html};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[derive(Debug, Template, Clone)]
 | 
				
			||||||
 | 
					#[template(path = "index.html")]
 | 
				
			||||||
 | 
					pub struct PageTemplate {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub async fn page() -> (StatusCode, Html<String>) {
 | 
				
			||||||
 | 
					    let page = PageTemplate {};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    (StatusCode::OK, Html(page.render().unwrap()))
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										8
									
								
								src/pages/mod.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								src/pages/mod.rs
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,8 @@
 | 
				
			||||||
 | 
					use askama::Template;
 | 
				
			||||||
 | 
					use axum::{Router, routing::get};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub mod index;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub fn register_routes() -> Router {
 | 
				
			||||||
 | 
					    Router::new().route("/", get(index::page))
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										27
									
								
								templates/base.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								templates/base.html
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,27 @@
 | 
				
			||||||
 | 
					<!DOCTYPE html>
 | 
				
			||||||
 | 
					<html lang="en">
 | 
				
			||||||
 | 
					    <head>
 | 
				
			||||||
 | 
					        <meta charset="UTF-8">
 | 
				
			||||||
 | 
					        <meta name="viewport" content="width=device-width, initial-scale=1">
 | 
				
			||||||
 | 
					        <title>{% block title %}{% endblock %}</title>
 | 
				
			||||||
 | 
					        <link href="css/global.css" rel="stylesheet">
 | 
				
			||||||
 | 
					        {% block headers %}{% endblock %}
 | 
				
			||||||
 | 
					    </head>
 | 
				
			||||||
 | 
					    <body>
 | 
				
			||||||
 | 
					        <div id="topnav">
 | 
				
			||||||
 | 
					            <div class="topnav_button" onclick="location.href='/'">
 | 
				
			||||||
 | 
					                 Dashboard
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
 | 
					            <div class="topnav_button" onclick="location.href='/roster'">
 | 
				
			||||||
 | 
					                 Roster
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
 | 
					            <div class="topnav_button" onclick="location.href='/events'">
 | 
				
			||||||
 | 
					                 Events
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
 | 
					            <div class="topnav_button" onclick="location.href='/documents'">
 | 
				
			||||||
 | 
					                 Documents
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
 | 
					            {% block content %}{% endblock %}
 | 
				
			||||||
 | 
					         </div>
 | 
				
			||||||
 | 
					    </body>
 | 
				
			||||||
 | 
					</html>
 | 
				
			||||||
							
								
								
									
										11
									
								
								templates/index.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								templates/index.html
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,11 @@
 | 
				
			||||||
 | 
					{% extends "base.html" %}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					{% block title %}Dashboard{% endblock %}
 | 
				
			||||||
 | 
					{% block headers %}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					{% endblock %}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					{% block content %}
 | 
				
			||||||
 | 
					    <h1>Hello!!!!!!!</h1>
 | 
				
			||||||
 | 
					{% endblock %}
 | 
				
			||||||
		Loading…
	
		Reference in New Issue
	
	Block a user