Add company management module with registration and entity switching
This commit is contained in:
parent
2760f00a30
commit
9468595395
151
actix_mvc_app/Cargo.lock
generated
151
actix_mvc_app/Cargo.lock
generated
@ -107,6 +107,45 @@ dependencies = [
|
|||||||
"syn",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "actix-multipart"
|
||||||
|
version = "0.6.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d974dd6c4f78d102d057c672dcf6faa618fafa9df91d44f9c466688fc1275a3a"
|
||||||
|
dependencies = [
|
||||||
|
"actix-multipart-derive",
|
||||||
|
"actix-utils",
|
||||||
|
"actix-web",
|
||||||
|
"bytes",
|
||||||
|
"derive_more 0.99.19",
|
||||||
|
"futures-core",
|
||||||
|
"futures-util",
|
||||||
|
"httparse",
|
||||||
|
"local-waker",
|
||||||
|
"log",
|
||||||
|
"memchr",
|
||||||
|
"mime",
|
||||||
|
"rand 0.8.5",
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
|
"serde_plain",
|
||||||
|
"tempfile",
|
||||||
|
"tokio",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "actix-multipart-derive"
|
||||||
|
version = "0.6.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0a0a77f836d869f700e5b47ac7c3c8b9c8bc82e4aec861954c6198abee3ebd4d"
|
||||||
|
dependencies = [
|
||||||
|
"darling",
|
||||||
|
"parse-size",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "actix-router"
|
name = "actix-router"
|
||||||
version = "0.5.3"
|
version = "0.5.3"
|
||||||
@ -247,6 +286,7 @@ version = "0.1.0"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"actix-files",
|
"actix-files",
|
||||||
"actix-identity",
|
"actix-identity",
|
||||||
|
"actix-multipart",
|
||||||
"actix-session",
|
"actix-session",
|
||||||
"actix-web",
|
"actix-web",
|
||||||
"bcrypt",
|
"bcrypt",
|
||||||
@ -255,6 +295,7 @@ dependencies = [
|
|||||||
"dotenv",
|
"dotenv",
|
||||||
"env_logger",
|
"env_logger",
|
||||||
"futures",
|
"futures",
|
||||||
|
"futures-util",
|
||||||
"jsonwebtoken",
|
"jsonwebtoken",
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
"log",
|
"log",
|
||||||
@ -823,6 +864,41 @@ dependencies = [
|
|||||||
"cipher",
|
"cipher",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "darling"
|
||||||
|
version = "0.20.11"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "fc7f46116c46ff9ab3eb1597a45688b6715c6e628b5c133e288e709a29bcb4ee"
|
||||||
|
dependencies = [
|
||||||
|
"darling_core",
|
||||||
|
"darling_macro",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "darling_core"
|
||||||
|
version = "0.20.11"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0d00b9596d185e565c2207a0b01f8bd1a135483d02d9b7b0a54b11da8d53412e"
|
||||||
|
dependencies = [
|
||||||
|
"fnv",
|
||||||
|
"ident_case",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"strsim",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "darling_macro"
|
||||||
|
version = "0.20.11"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead"
|
||||||
|
dependencies = [
|
||||||
|
"darling_core",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "deranged"
|
name = "deranged"
|
||||||
version = "0.4.0"
|
version = "0.4.0"
|
||||||
@ -947,6 +1023,22 @@ version = "1.0.2"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
|
checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "errno"
|
||||||
|
version = "0.3.11"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "976dd42dc7e85965fe702eb8164f21f450704bdde31faefd6471dba214cb594e"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
"windows-sys 0.59.0",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "fastrand"
|
||||||
|
version = "2.3.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "flate2"
|
name = "flate2"
|
||||||
version = "1.1.1"
|
version = "1.1.1"
|
||||||
@ -1397,6 +1489,12 @@ dependencies = [
|
|||||||
"syn",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ident_case"
|
||||||
|
version = "1.0.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "idna"
|
name = "idna"
|
||||||
version = "1.0.3"
|
version = "1.0.3"
|
||||||
@ -1564,6 +1662,12 @@ version = "0.2.11"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8355be11b20d696c8f18f6cc018c4e372165b1fa8126cef092399c9951984ffa"
|
checksum = "8355be11b20d696c8f18f6cc018c4e372165b1fa8126cef092399c9951984ffa"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "linux-raw-sys"
|
||||||
|
version = "0.9.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cd945864f07fe9f5371a27ad7b52a172b4b499999f1d97574c9fa68373937e12"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "litemap"
|
name = "litemap"
|
||||||
version = "0.7.5"
|
version = "0.7.5"
|
||||||
@ -1760,6 +1864,12 @@ dependencies = [
|
|||||||
"windows-targets",
|
"windows-targets",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "parse-size"
|
||||||
|
version = "1.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "487f2ccd1e17ce8c1bfab3a65c89525af41cfad4c8659021a1e9a2aacd73b89b"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "parse-zoneinfo"
|
name = "parse-zoneinfo"
|
||||||
version = "0.3.1"
|
version = "0.3.1"
|
||||||
@ -2152,6 +2262,19 @@ dependencies = [
|
|||||||
"semver",
|
"semver",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustix"
|
||||||
|
version = "1.0.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c71e83d6afe7ff64890ec6b71d6a69bb8a610ab78ce364b3352876bb4c801266"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags",
|
||||||
|
"errno",
|
||||||
|
"libc",
|
||||||
|
"linux-raw-sys",
|
||||||
|
"windows-sys 0.59.0",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustversion"
|
name = "rustversion"
|
||||||
version = "1.0.20"
|
version = "1.0.20"
|
||||||
@ -2217,6 +2340,15 @@ dependencies = [
|
|||||||
"serde",
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde_plain"
|
||||||
|
version = "1.0.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9ce1fc6db65a611022b23a0dec6975d63fb80a302cb3388835ff02c097258d50"
|
||||||
|
dependencies = [
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_spanned"
|
name = "serde_spanned"
|
||||||
version = "0.6.8"
|
version = "0.6.8"
|
||||||
@ -2356,6 +2488,12 @@ version = "1.2.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3"
|
checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "strsim"
|
||||||
|
version = "0.11.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "subtle"
|
name = "subtle"
|
||||||
version = "2.6.1"
|
version = "2.6.1"
|
||||||
@ -2384,6 +2522,19 @@ dependencies = [
|
|||||||
"syn",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tempfile"
|
||||||
|
version = "3.19.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7437ac7763b9b123ccf33c338a5cc1bac6f69b45a136c19bdd8a65e3916435bf"
|
||||||
|
dependencies = [
|
||||||
|
"fastrand",
|
||||||
|
"getrandom 0.3.2",
|
||||||
|
"once_cell",
|
||||||
|
"rustix",
|
||||||
|
"windows-sys 0.59.0",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tera"
|
name = "tera"
|
||||||
version = "1.20.0"
|
version = "1.20.0"
|
||||||
|
@ -4,6 +4,8 @@ version = "0.1.0"
|
|||||||
edition = "2024"
|
edition = "2024"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
actix-multipart = "0.6.1"
|
||||||
|
futures-util = "0.3.30"
|
||||||
actix-web = "4.5.1"
|
actix-web = "4.5.1"
|
||||||
actix-files = "0.6.5"
|
actix-files = "0.6.5"
|
||||||
tera = "1.19.1"
|
tera = "1.19.1"
|
||||||
|
245
actix_mvc_app/src/controllers/company.rs
Normal file
245
actix_mvc_app/src/controllers/company.rs
Normal file
@ -0,0 +1,245 @@
|
|||||||
|
use actix_web::{web, HttpResponse, Responder, Result};
|
||||||
|
use actix_web::HttpRequest;
|
||||||
|
use tera::{Context, Tera};
|
||||||
|
use serde::Deserialize;
|
||||||
|
use chrono::Utc;
|
||||||
|
use crate::utils::render_template;
|
||||||
|
|
||||||
|
// Form structs for company operations
|
||||||
|
#[derive(Debug, Deserialize)]
|
||||||
|
pub struct CompanyRegistrationForm {
|
||||||
|
pub company_name: String,
|
||||||
|
pub company_type: String,
|
||||||
|
pub shareholders: String,
|
||||||
|
pub company_purpose: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct CompanyController;
|
||||||
|
|
||||||
|
impl CompanyController {
|
||||||
|
// Display the company management dashboard
|
||||||
|
pub async fn index(tmpl: web::Data<Tera>, req: HttpRequest) -> Result<HttpResponse> {
|
||||||
|
let mut context = Context::new();
|
||||||
|
|
||||||
|
println!("DEBUG: Starting Company dashboard rendering");
|
||||||
|
|
||||||
|
// Add active_page for navigation highlighting
|
||||||
|
context.insert("active_page", &"company");
|
||||||
|
|
||||||
|
// Parse query parameters
|
||||||
|
let query_string = req.query_string();
|
||||||
|
|
||||||
|
// Check for success message
|
||||||
|
if let Some(pos) = query_string.find("success=") {
|
||||||
|
let start = pos + 8; // length of "success="
|
||||||
|
let end = query_string[start..].find('&').map_or(query_string.len(), |e| e + start);
|
||||||
|
let success = &query_string[start..end];
|
||||||
|
let decoded = urlencoding::decode(success).unwrap_or_else(|_| success.into());
|
||||||
|
context.insert("success", &decoded);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check for entity context
|
||||||
|
if let Some(pos) = query_string.find("entity=") {
|
||||||
|
let start = pos + 7; // length of "entity="
|
||||||
|
let end = query_string[start..].find('&').map_or(query_string.len(), |e| e + start);
|
||||||
|
let entity = &query_string[start..end];
|
||||||
|
context.insert("entity", &entity);
|
||||||
|
|
||||||
|
// Also get entity name if present
|
||||||
|
if let Some(pos) = query_string.find("entity_name=") {
|
||||||
|
let start = pos + 12; // length of "entity_name="
|
||||||
|
let end = query_string[start..].find('&').map_or(query_string.len(), |e| e + start);
|
||||||
|
let entity_name = &query_string[start..end];
|
||||||
|
let decoded_name = urlencoding::decode(entity_name).unwrap_or_else(|_| entity_name.into());
|
||||||
|
context.insert("entity_name", &decoded_name);
|
||||||
|
println!("DEBUG: Entity context set to {} ({})", entity, decoded_name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
println!("DEBUG: Rendering Company dashboard template");
|
||||||
|
let response = render_template(&tmpl, "company/index.html", &context);
|
||||||
|
println!("DEBUG: Finished rendering Company dashboard template");
|
||||||
|
response
|
||||||
|
}
|
||||||
|
|
||||||
|
// View company details
|
||||||
|
pub async fn view_company(tmpl: web::Data<Tera>, path: web::Path<String>) -> Result<HttpResponse> {
|
||||||
|
let company_id = path.into_inner();
|
||||||
|
let mut context = Context::new();
|
||||||
|
|
||||||
|
println!("DEBUG: Viewing company details for {}", company_id);
|
||||||
|
|
||||||
|
// Add active_page for navigation highlighting
|
||||||
|
context.insert("active_page", &"company");
|
||||||
|
context.insert("company_id", &company_id);
|
||||||
|
|
||||||
|
// In a real application, we would fetch company data from a database
|
||||||
|
// For now, we'll use mock data based on the company_id
|
||||||
|
match company_id.as_str() {
|
||||||
|
"company1" => {
|
||||||
|
context.insert("company_name", &"Zanzibar Digital Solutions");
|
||||||
|
context.insert("company_type", &"Startup FZC");
|
||||||
|
context.insert("status", &"Active");
|
||||||
|
context.insert("registration_date", &"2025-04-01");
|
||||||
|
context.insert("purpose", &"Digital solutions and blockchain development");
|
||||||
|
context.insert("plan", &"Startup FZC - $50/month");
|
||||||
|
context.insert("next_billing", &"2025-06-01");
|
||||||
|
context.insert("payment_method", &"Credit Card (****4582)");
|
||||||
|
|
||||||
|
// Shareholders data
|
||||||
|
let shareholders = vec![
|
||||||
|
("John Smith", "60%"),
|
||||||
|
("Sarah Johnson", "40%"),
|
||||||
|
];
|
||||||
|
context.insert("shareholders", &shareholders);
|
||||||
|
|
||||||
|
// Contracts data
|
||||||
|
let contracts = vec![
|
||||||
|
("Articles of Incorporation", "Signed"),
|
||||||
|
("Terms & Conditions", "Signed"),
|
||||||
|
("Digital Asset Issuance", "Signed"),
|
||||||
|
];
|
||||||
|
context.insert("contracts", &contracts);
|
||||||
|
},
|
||||||
|
"company2" => {
|
||||||
|
context.insert("company_name", &"Blockchain Innovations Ltd");
|
||||||
|
context.insert("company_type", &"Growth FZC");
|
||||||
|
context.insert("status", &"Active");
|
||||||
|
context.insert("registration_date", &"2025-03-15");
|
||||||
|
context.insert("purpose", &"Blockchain technology research and development");
|
||||||
|
context.insert("plan", &"Growth FZC - $100/month");
|
||||||
|
context.insert("next_billing", &"2025-06-15");
|
||||||
|
context.insert("payment_method", &"Bank Transfer");
|
||||||
|
|
||||||
|
// Shareholders data
|
||||||
|
let shareholders = vec![
|
||||||
|
("Michael Chen", "35%"),
|
||||||
|
("Aisha Patel", "35%"),
|
||||||
|
("David Okonkwo", "30%"),
|
||||||
|
];
|
||||||
|
context.insert("shareholders", &shareholders);
|
||||||
|
|
||||||
|
// Contracts data
|
||||||
|
let contracts = vec![
|
||||||
|
("Articles of Incorporation", "Signed"),
|
||||||
|
("Terms & Conditions", "Signed"),
|
||||||
|
("Digital Asset Issuance", "Signed"),
|
||||||
|
("Physical Asset Holding", "Signed"),
|
||||||
|
];
|
||||||
|
context.insert("contracts", &contracts);
|
||||||
|
},
|
||||||
|
"company3" => {
|
||||||
|
context.insert("company_name", &"Sustainable Energy Cooperative");
|
||||||
|
context.insert("company_type", &"Cooperative FZC");
|
||||||
|
context.insert("status", &"Pending");
|
||||||
|
context.insert("registration_date", &"2025-05-01");
|
||||||
|
context.insert("purpose", &"Renewable energy production and distribution");
|
||||||
|
context.insert("plan", &"Cooperative FZC - $200/month");
|
||||||
|
context.insert("next_billing", &"Pending Activation");
|
||||||
|
context.insert("payment_method", &"Pending");
|
||||||
|
|
||||||
|
// Shareholders data
|
||||||
|
let shareholders = vec![
|
||||||
|
("Community Energy Group", "40%"),
|
||||||
|
("Green Future Initiative", "30%"),
|
||||||
|
("Sustainable Living Collective", "30%"),
|
||||||
|
];
|
||||||
|
context.insert("shareholders", &shareholders);
|
||||||
|
|
||||||
|
// Contracts data
|
||||||
|
let contracts = vec![
|
||||||
|
("Articles of Incorporation", "Signed"),
|
||||||
|
("Terms & Conditions", "Signed"),
|
||||||
|
("Cooperative Governance", "Pending"),
|
||||||
|
];
|
||||||
|
context.insert("contracts", &contracts);
|
||||||
|
},
|
||||||
|
_ => {
|
||||||
|
// If company_id is not recognized, redirect to company index
|
||||||
|
return Ok(HttpResponse::Found()
|
||||||
|
.append_header(("Location", "/company"))
|
||||||
|
.finish());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
println!("DEBUG: Rendering company view template");
|
||||||
|
let response = render_template(&tmpl, "company/view.html", &context);
|
||||||
|
println!("DEBUG: Finished rendering company view template");
|
||||||
|
response
|
||||||
|
}
|
||||||
|
|
||||||
|
// Switch to entity context
|
||||||
|
pub async fn switch_entity(path: web::Path<String>) -> Result<HttpResponse> {
|
||||||
|
let company_id = path.into_inner();
|
||||||
|
|
||||||
|
println!("DEBUG: Switching to entity context for {}", company_id);
|
||||||
|
|
||||||
|
// Get company name based on ID (in a real app, this would come from a database)
|
||||||
|
let company_name = match company_id.as_str() {
|
||||||
|
"company1" => "Zanzibar Digital Solutions",
|
||||||
|
"company2" => "Blockchain Innovations Ltd",
|
||||||
|
"company3" => "Sustainable Energy Cooperative",
|
||||||
|
_ => "Unknown Company"
|
||||||
|
};
|
||||||
|
|
||||||
|
// In a real application, we would set a session/cookie for the current entity
|
||||||
|
// Here we'll redirect back to the company page with a success message and entity parameter
|
||||||
|
let success_message = format!("Switched to {} entity context", company_name);
|
||||||
|
let encoded_message = urlencoding::encode(&success_message);
|
||||||
|
|
||||||
|
Ok(HttpResponse::Found()
|
||||||
|
.append_header(("Location", format!("/company?success={}&entity={}&entity_name={}",
|
||||||
|
encoded_message, company_id, urlencoding::encode(company_name))))
|
||||||
|
.finish())
|
||||||
|
}
|
||||||
|
|
||||||
|
// Process company registration
|
||||||
|
pub async fn register(
|
||||||
|
mut form: actix_multipart::Multipart,
|
||||||
|
) -> Result<HttpResponse> {
|
||||||
|
use actix_web::{http::header};
|
||||||
|
use futures_util::stream::StreamExt as _;
|
||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
println!("DEBUG: Processing company registration request");
|
||||||
|
|
||||||
|
let mut fields: HashMap<String, String> = HashMap::new();
|
||||||
|
let mut files = Vec::new();
|
||||||
|
|
||||||
|
// Parse multipart form
|
||||||
|
while let Some(Ok(mut field)) = form.next().await {
|
||||||
|
let mut value = Vec::new();
|
||||||
|
while let Some(chunk) = field.next().await {
|
||||||
|
let data = chunk.unwrap();
|
||||||
|
value.extend_from_slice(&data);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get field name from content disposition
|
||||||
|
let cd = field.content_disposition();
|
||||||
|
if let Some(name) = cd.get_name() {
|
||||||
|
if name == "company_docs" {
|
||||||
|
files.push(value); // Just collect files in memory for now
|
||||||
|
} else {
|
||||||
|
fields.insert(name.to_string(), String::from_utf8_lossy(&value).to_string());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Extract company details
|
||||||
|
let company_name = fields.get("company_name").cloned().unwrap_or_default();
|
||||||
|
let company_type = fields.get("company_type").cloned().unwrap_or_default();
|
||||||
|
let shareholders = fields.get("shareholders").cloned().unwrap_or_default();
|
||||||
|
|
||||||
|
// Log received fields (mock DB insert)
|
||||||
|
println!("[Company Registration] Name: {}, Type: {}, Shareholders: {}, Files: {}",
|
||||||
|
company_name, company_type, shareholders, files.len());
|
||||||
|
|
||||||
|
// Create success message
|
||||||
|
let success_message = format!("Successfully registered {} as a {}", company_name, company_type);
|
||||||
|
|
||||||
|
// Redirect back to /company with success message
|
||||||
|
Ok(HttpResponse::SeeOther()
|
||||||
|
.append_header((header::LOCATION, format!("/company?success={}", urlencoding::encode(&success_message))))
|
||||||
|
.finish())
|
||||||
|
}
|
||||||
|
}
|
@ -9,5 +9,6 @@ pub mod contract;
|
|||||||
pub mod asset;
|
pub mod asset;
|
||||||
pub mod defi;
|
pub mod defi;
|
||||||
pub mod marketplace;
|
pub mod marketplace;
|
||||||
|
pub mod company;
|
||||||
|
|
||||||
// Re-export controllers for easier imports
|
// Re-export controllers for easier imports
|
||||||
|
@ -10,6 +10,7 @@ use crate::controllers::contract::ContractController;
|
|||||||
use crate::controllers::asset::AssetController;
|
use crate::controllers::asset::AssetController;
|
||||||
use crate::controllers::marketplace::MarketplaceController;
|
use crate::controllers::marketplace::MarketplaceController;
|
||||||
use crate::controllers::defi::DefiController;
|
use crate::controllers::defi::DefiController;
|
||||||
|
use crate::controllers::company::CompanyController;
|
||||||
use crate::middleware::JwtAuth;
|
use crate::middleware::JwtAuth;
|
||||||
use crate::SESSION_KEY;
|
use crate::SESSION_KEY;
|
||||||
|
|
||||||
@ -133,6 +134,14 @@ pub fn configure_routes(cfg: &mut web::ServiceConfig) {
|
|||||||
.route("/swap", web::post().to(DefiController::swap_tokens))
|
.route("/swap", web::post().to(DefiController::swap_tokens))
|
||||||
.route("/collateral", web::post().to(DefiController::create_collateral))
|
.route("/collateral", web::post().to(DefiController::create_collateral))
|
||||||
)
|
)
|
||||||
|
// Company routes
|
||||||
|
.service(
|
||||||
|
web::scope("/company")
|
||||||
|
.route("", web::get().to(CompanyController::index))
|
||||||
|
.route("/register", web::post().to(CompanyController::register))
|
||||||
|
.route("/view/{id}", web::get().to(CompanyController::view_company))
|
||||||
|
.route("/switch/{id}", web::get().to(CompanyController::switch_entity))
|
||||||
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
// Keep the /protected scope for any future routes that should be under that path
|
// Keep the /protected scope for any future routes that should be under that path
|
||||||
|
173
actix_mvc_app/src/static/js/company.js
Normal file
173
actix_mvc_app/src/static/js/company.js
Normal file
@ -0,0 +1,173 @@
|
|||||||
|
// Company data (would be loaded from backend in production)
|
||||||
|
var companyData = {
|
||||||
|
'company1': {
|
||||||
|
name: 'Zanzibar Digital Solutions',
|
||||||
|
type: 'Startup FZC',
|
||||||
|
status: 'Active',
|
||||||
|
registrationDate: '2025-04-01',
|
||||||
|
purpose: 'Digital solutions and blockchain development',
|
||||||
|
plan: 'Startup FZC - $50/month',
|
||||||
|
nextBilling: '2025-06-01',
|
||||||
|
paymentMethod: 'Credit Card (****4582)',
|
||||||
|
shareholders: [
|
||||||
|
{ name: 'John Smith', percentage: '60%' },
|
||||||
|
{ name: 'Sarah Johnson', percentage: '40%' }
|
||||||
|
],
|
||||||
|
contracts: [
|
||||||
|
{ name: 'Articles of Incorporation', status: 'Signed' },
|
||||||
|
{ name: 'Terms & Conditions', status: 'Signed' },
|
||||||
|
{ name: 'Digital Asset Issuance', status: 'Signed' }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
'company2': {
|
||||||
|
name: 'Blockchain Innovations Ltd',
|
||||||
|
type: 'Growth FZC',
|
||||||
|
status: 'Active',
|
||||||
|
registrationDate: '2025-03-15',
|
||||||
|
purpose: 'Blockchain technology research and development',
|
||||||
|
plan: 'Growth FZC - $100/month',
|
||||||
|
nextBilling: '2025-06-15',
|
||||||
|
paymentMethod: 'Bank Transfer',
|
||||||
|
shareholders: [
|
||||||
|
{ name: 'Michael Chen', percentage: '35%' },
|
||||||
|
{ name: 'Aisha Patel', percentage: '35%' },
|
||||||
|
{ name: 'David Okonkwo', percentage: '30%' }
|
||||||
|
],
|
||||||
|
contracts: [
|
||||||
|
{ name: 'Articles of Incorporation', status: 'Signed' },
|
||||||
|
{ name: 'Terms & Conditions', status: 'Signed' },
|
||||||
|
{ name: 'Digital Asset Issuance', status: 'Signed' },
|
||||||
|
{ name: 'Physical Asset Holding', status: 'Signed' }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
'company3': {
|
||||||
|
name: 'Sustainable Energy Cooperative',
|
||||||
|
type: 'Cooperative FZC',
|
||||||
|
status: 'Pending',
|
||||||
|
registrationDate: '2025-05-01',
|
||||||
|
purpose: 'Renewable energy production and distribution',
|
||||||
|
plan: 'Cooperative FZC - $200/month',
|
||||||
|
nextBilling: 'Pending Activation',
|
||||||
|
paymentMethod: 'Pending',
|
||||||
|
shareholders: [
|
||||||
|
{ name: 'Community Energy Group', percentage: '40%' },
|
||||||
|
{ name: 'Green Future Initiative', percentage: '30%' },
|
||||||
|
{ name: 'Sustainable Living Collective', percentage: '30%' }
|
||||||
|
],
|
||||||
|
contracts: [
|
||||||
|
{ name: 'Articles of Incorporation', status: 'Signed' },
|
||||||
|
{ name: 'Terms & Conditions', status: 'Signed' },
|
||||||
|
{ name: 'Cooperative Governance', status: 'Pending' }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Current company ID for modal
|
||||||
|
var currentCompanyId = null;
|
||||||
|
|
||||||
|
// View company details function
|
||||||
|
function viewCompanyDetails(companyId) {
|
||||||
|
// Store current company ID
|
||||||
|
currentCompanyId = companyId;
|
||||||
|
|
||||||
|
// Get company data
|
||||||
|
const company = companyData[companyId];
|
||||||
|
if (!company) return;
|
||||||
|
|
||||||
|
// Update modal title
|
||||||
|
document.getElementById('companyDetailsModalLabel').innerHTML =
|
||||||
|
`<i class="bi bi-building me-2"></i>${company.name} Details`;
|
||||||
|
|
||||||
|
// Update general information
|
||||||
|
document.getElementById('modal-company-name').textContent = company.name;
|
||||||
|
document.getElementById('modal-company-type').textContent = company.type;
|
||||||
|
document.getElementById('modal-registration-date').textContent = company.registrationDate;
|
||||||
|
|
||||||
|
// Update status with appropriate badge
|
||||||
|
const statusBadge = company.status === 'Active' ?
|
||||||
|
`<span class="badge bg-success">${company.status}</span>` :
|
||||||
|
`<span class="badge bg-warning text-dark">${company.status}</span>`;
|
||||||
|
document.getElementById('modal-status').innerHTML = statusBadge;
|
||||||
|
|
||||||
|
document.getElementById('modal-purpose').textContent = company.purpose;
|
||||||
|
|
||||||
|
// Update billing information
|
||||||
|
document.getElementById('modal-plan').textContent = company.plan;
|
||||||
|
document.getElementById('modal-next-billing').textContent = company.nextBilling;
|
||||||
|
document.getElementById('modal-payment-method').textContent = company.paymentMethod;
|
||||||
|
|
||||||
|
// Update shareholders table
|
||||||
|
const shareholdersTable = document.getElementById('modal-shareholders');
|
||||||
|
shareholdersTable.innerHTML = '';
|
||||||
|
company.shareholders.forEach(shareholder => {
|
||||||
|
const row = document.createElement('tr');
|
||||||
|
row.innerHTML = `
|
||||||
|
<td>${shareholder.name}</td>
|
||||||
|
<td>${shareholder.percentage}</td>
|
||||||
|
`;
|
||||||
|
shareholdersTable.appendChild(row);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Update contracts table
|
||||||
|
const contractsTable = document.getElementById('modal-contracts');
|
||||||
|
contractsTable.innerHTML = '';
|
||||||
|
company.contracts.forEach(contract => {
|
||||||
|
const row = document.createElement('tr');
|
||||||
|
const statusBadge = contract.status === 'Signed' ?
|
||||||
|
`<span class="badge bg-success">${contract.status}</span>` :
|
||||||
|
`<span class="badge bg-warning text-dark">${contract.status}</span>`;
|
||||||
|
|
||||||
|
row.innerHTML = `
|
||||||
|
<td>${contract.name}</td>
|
||||||
|
<td>${statusBadge}</td>
|
||||||
|
<td><button class="btn btn-sm btn-outline-primary" onclick="viewContract('${contract.name.toLowerCase().replace(/\s+/g, '-')}')">View</button></td>
|
||||||
|
`;
|
||||||
|
contractsTable.appendChild(row);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Show the modal
|
||||||
|
const modal = new bootstrap.Modal(document.getElementById('companyDetailsModal'));
|
||||||
|
modal.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Switch to entity function
|
||||||
|
function switchToEntity(companyId) {
|
||||||
|
const company = companyData[companyId];
|
||||||
|
if (!company) return;
|
||||||
|
|
||||||
|
// In a real application, this would redirect to the entity context
|
||||||
|
// For now, we'll just show an alert
|
||||||
|
alert(`Switching to ${company.name} entity context. All UI will now reflect this entity's governance, billing, and other features.`);
|
||||||
|
|
||||||
|
// This would typically involve:
|
||||||
|
// 1. Setting a session/cookie for the current entity
|
||||||
|
// 2. Redirecting to the dashboard with that entity context
|
||||||
|
// window.location.href = `/dashboard?entity=${companyId}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Switch to entity from modal
|
||||||
|
function switchToEntityFromModal() {
|
||||||
|
if (currentCompanyId) {
|
||||||
|
switchToEntity(currentCompanyId);
|
||||||
|
// Close the modal
|
||||||
|
const modal = bootstrap.Modal.getInstance(document.getElementById('companyDetailsModal'));
|
||||||
|
modal.hide();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// View contract function
|
||||||
|
function viewContract(contractId) {
|
||||||
|
// In a real application, this would open the contract document
|
||||||
|
// For now, we'll just show an alert
|
||||||
|
alert(`Viewing contract: ${contractId.replace(/-/g, ' ')}`);
|
||||||
|
|
||||||
|
// This would typically involve:
|
||||||
|
// 1. Fetching the contract document from the server
|
||||||
|
// 2. Opening it in a viewer or new tab
|
||||||
|
// window.open(`/contracts/view/${contractId}`, '_blank');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize when DOM is loaded
|
||||||
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
|
console.log('Company management script loaded');
|
||||||
|
});
|
@ -64,7 +64,7 @@
|
|||||||
<button class="navbar-toggler d-md-none me-2" type="button" id="sidebarToggle" aria-label="Toggle navigation">
|
<button class="navbar-toggler d-md-none me-2" type="button" id="sidebarToggle" aria-label="Toggle navigation">
|
||||||
<i class="bi bi-list text-white"></i>
|
<i class="bi bi-list text-white"></i>
|
||||||
</button>
|
</button>
|
||||||
<h5 class="mb-0">Zanzibar Digital Freezone</h5>
|
<h5 class="mb-0">Zanzibar Digital Freezone {% if entity_name %}| <span class="text-info">{{ entity_name }}</span>{% endif %}</h5>
|
||||||
</div>
|
</div>
|
||||||
<div class="d-none d-md-flex">
|
<div class="d-none d-md-flex">
|
||||||
<ul class="navbar-nav flex-row">
|
<ul class="navbar-nav flex-row">
|
||||||
@ -155,6 +155,11 @@
|
|||||||
<i class="bi bi-bank me-2"></i> DeFi Platform
|
<i class="bi bi-bank me-2"></i> DeFi Platform
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<a class="nav-link d-flex align-items-center ps-3 py-2 {% if active_page == 'company' %}active fw-bold border-start border-4 border-primary bg-light{% endif %}" href="/company">
|
||||||
|
<i class="bi bi-building me-2"></i> Companies
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a class="nav-link d-flex align-items-center ps-3 py-2 {% if active_page == 'marketplace' %}active fw-bold border-start border-4 border-primary bg-light{% endif %}" href="/marketplace">
|
<a class="nav-link d-flex align-items-center ps-3 py-2 {% if active_page == 'marketplace' %}active fw-bold border-start border-4 border-primary bg-light{% endif %}" href="/marketplace">
|
||||||
<i class="bi bi-shop me-2"></i> Marketplace
|
<i class="bi bi-shop me-2"></i> Marketplace
|
||||||
@ -206,6 +211,33 @@
|
|||||||
</footer>
|
</footer>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- Toast container for notifications -->
|
||||||
|
<div class="toast-container position-fixed bottom-0 end-0 p-3">
|
||||||
|
{% if success %}
|
||||||
|
<div class="toast show" role="alert" aria-live="assertive" aria-atomic="true">
|
||||||
|
<div class="toast-header bg-success text-white">
|
||||||
|
<strong class="me-auto">Success</strong>
|
||||||
|
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="toast" aria-label="Close"></button>
|
||||||
|
</div>
|
||||||
|
<div class="toast-body">
|
||||||
|
{{ success }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if error %}
|
||||||
|
<div class="toast show" role="alert" aria-live="assertive" aria-atomic="true">
|
||||||
|
<div class="toast-header bg-danger text-white">
|
||||||
|
<strong class="me-auto">Error</strong>
|
||||||
|
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="toast" aria-label="Close"></button>
|
||||||
|
</div>
|
||||||
|
<div class="toast-body">
|
||||||
|
{{ error }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
|
||||||
<script src="/static/js/bootstrap.bundle.min.js"></script>
|
<script src="/static/js/bootstrap.bundle.min.js"></script>
|
||||||
<script src="https://unpkg.com/unpoly@3.7.2/unpoly.min.js"></script>
|
<script src="https://unpkg.com/unpoly@3.7.2/unpoly.min.js"></script>
|
||||||
<script src="https://unpkg.com/unpoly@3.7.2/unpoly-bootstrap5.min.js"></script>
|
<script src="https://unpkg.com/unpoly@3.7.2/unpoly-bootstrap5.min.js"></script>
|
||||||
@ -214,6 +246,17 @@
|
|||||||
document.getElementById('sidebarToggle').addEventListener('click', function() {
|
document.getElementById('sidebarToggle').addEventListener('click', function() {
|
||||||
document.getElementById('sidebar').classList.toggle('show');
|
document.getElementById('sidebar').classList.toggle('show');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Auto-hide toasts after 5 seconds
|
||||||
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
|
const toasts = document.querySelectorAll('.toast.show');
|
||||||
|
toasts.forEach(toast => {
|
||||||
|
setTimeout(() => {
|
||||||
|
const bsToast = new bootstrap.Toast(toast);
|
||||||
|
bsToast.hide();
|
||||||
|
}, 5000);
|
||||||
|
});
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
{% block extra_js %}{% endblock %}
|
{% block extra_js %}{% endblock %}
|
||||||
</body>
|
</body>
|
||||||
|
111
actix_mvc_app/src/views/company/index.html
Normal file
111
actix_mvc_app/src/views/company/index.html
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
{% extends "base.html" %}
|
||||||
|
|
||||||
|
{% block title %}Company Management{% endblock %}
|
||||||
|
|
||||||
|
{% block head %}
|
||||||
|
{{ super() }}
|
||||||
|
<style>
|
||||||
|
.toast {
|
||||||
|
position: fixed;
|
||||||
|
top: 20px;
|
||||||
|
right: 20px;
|
||||||
|
z-index: 9999;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<!-- Toast notification for success messages -->
|
||||||
|
{% if success_message %}
|
||||||
|
<div class="position-fixed bottom-0 end-0 p-3" style="z-index: 11">
|
||||||
|
<div class="toast show" role="alert" aria-live="assertive" aria-atomic="true" data-bs-autohide="true" data-bs-delay="5000">
|
||||||
|
<div class="toast-header bg-success text-white">
|
||||||
|
<i class="bi bi-check-circle me-2"></i>
|
||||||
|
<strong class="me-auto">Success</strong>
|
||||||
|
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="toast" aria-label="Close"></button>
|
||||||
|
</div>
|
||||||
|
<div class="toast-body">
|
||||||
|
{{ success_message }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
<div class="container-fluid py-4">
|
||||||
|
<h2 class="mb-4">Company & Legal Entity Management (Freezone)</h2>
|
||||||
|
|
||||||
|
<!-- Company Management Tabs -->
|
||||||
|
<div class="mb-4">
|
||||||
|
<div class="card-body">
|
||||||
|
<ul class="nav nav-tabs" id="companyTabs" role="tablist">
|
||||||
|
<li class="nav-item" role="presentation">
|
||||||
|
<button class="nav-link active" id="manage-tab" data-bs-toggle="tab" data-bs-target="#manage" type="button" role="tab" aria-controls="manage" aria-selected="true">
|
||||||
|
<i class="bi bi-building me-1"></i> Manage Companies
|
||||||
|
</button>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item" role="presentation">
|
||||||
|
<button class="nav-link" id="register-tab" data-bs-toggle="tab" data-bs-target="#register" type="button" role="tab" aria-controls="register" aria-selected="false">
|
||||||
|
<i class="bi bi-file-earmark-plus me-1"></i> Register New Company
|
||||||
|
</button>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<div class="tab-content mt-3" id="companyTabsContent">
|
||||||
|
<div class="tab-pane fade show active" id="manage" role="tabpanel" aria-labelledby="manage-tab">
|
||||||
|
{% include "company/manage.html" %}
|
||||||
|
</div>
|
||||||
|
<div class="tab-pane fade" id="register" role="tabpanel" aria-labelledby="register-tab">
|
||||||
|
{% include "company/register.html" %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block scripts %}
|
||||||
|
{{ super() }}
|
||||||
|
<script src="/static/js/company.js"></script>
|
||||||
|
<script>
|
||||||
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
|
// Show toast if success message exists
|
||||||
|
const urlParams = new URLSearchParams(window.location.search);
|
||||||
|
const successMessage = urlParams.get('success');
|
||||||
|
if (successMessage) {
|
||||||
|
const toastEl = document.querySelector('.toast');
|
||||||
|
if (toastEl) {
|
||||||
|
const toastBody = toastEl.querySelector('.toast-body');
|
||||||
|
toastBody.textContent = decodeURIComponent(successMessage);
|
||||||
|
const toast = new bootstrap.Toast(toastEl);
|
||||||
|
toast.show();
|
||||||
|
|
||||||
|
// Auto-hide after 5 seconds
|
||||||
|
setTimeout(function() {
|
||||||
|
toast.hide();
|
||||||
|
}, 5000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle tab tracking in URL
|
||||||
|
const tabParam = urlParams.get('tab');
|
||||||
|
if (tabParam) {
|
||||||
|
const tabButton = document.querySelector(`button[data-bs-target="#${tabParam}"]`);
|
||||||
|
if (tabButton) {
|
||||||
|
const tab = new bootstrap.Tab(tabButton);
|
||||||
|
tab.show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update URL when tab changes
|
||||||
|
const tabButtons = document.querySelectorAll('button[data-bs-toggle="tab"]');
|
||||||
|
tabButtons.forEach(function(button) {
|
||||||
|
button.addEventListener('shown.bs.tab', function(event) {
|
||||||
|
const targetId = event.target.getAttribute('data-bs-target').substring(1);
|
||||||
|
const url = new URL(window.location);
|
||||||
|
url.searchParams.set('tab', targetId);
|
||||||
|
window.history.replaceState({}, '', url);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
{% endblock %}
|
193
actix_mvc_app/src/views/company/manage.html
Normal file
193
actix_mvc_app/src/views/company/manage.html
Normal file
@ -0,0 +1,193 @@
|
|||||||
|
<div class="card mb-4">
|
||||||
|
<div class="card-header bg-primary text-white">
|
||||||
|
<i class="bi bi-building me-1"></i> Your Companies
|
||||||
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<!-- Company list table -->
|
||||||
|
<table class="table table-hover align-middle">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Name</th>
|
||||||
|
<th>Type</th>
|
||||||
|
<th>Status</th>
|
||||||
|
<th>Date Registered</th>
|
||||||
|
<th>Actions</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<!-- Example rows -->
|
||||||
|
<tr>
|
||||||
|
<td>Zanzibar Digital Solutions</td>
|
||||||
|
<td>Startup FZC</td>
|
||||||
|
<td><span class="badge bg-success">Active</span></td>
|
||||||
|
<td>2025-04-01</td>
|
||||||
|
<td>
|
||||||
|
<div class="btn-group">
|
||||||
|
<a href="/company/view/company1" class="btn btn-sm btn-outline-primary"><i class="bi bi-eye"></i> View</a>
|
||||||
|
<a href="/company/switch/company1" class="btn btn-sm btn-primary"><i class="bi bi-box-arrow-in-right"></i> Switch to Entity</a>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Blockchain Innovations Ltd</td>
|
||||||
|
<td>Growth FZC</td>
|
||||||
|
<td><span class="badge bg-success">Active</span></td>
|
||||||
|
<td>2025-03-15</td>
|
||||||
|
<td>
|
||||||
|
<div class="btn-group">
|
||||||
|
<a href="/company/view/company2" class="btn btn-sm btn-outline-primary"><i class="bi bi-eye"></i> View</a>
|
||||||
|
<a href="/company/switch/company2" class="btn btn-sm btn-primary"><i class="bi bi-box-arrow-in-right"></i> Switch to Entity</a>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Sustainable Energy Cooperative</td>
|
||||||
|
<td>Cooperative FZC</td>
|
||||||
|
<td><span class="badge bg-warning text-dark">Pending</span></td>
|
||||||
|
<td>2025-05-01</td>
|
||||||
|
<td>
|
||||||
|
<div class="btn-group">
|
||||||
|
<a href="/company/view/company3" class="btn btn-sm btn-outline-primary"><i class="bi bi-eye"></i> View</a>
|
||||||
|
<a href="/company/switch/company3" class="btn btn-sm btn-primary"><i class="bi bi-box-arrow-in-right"></i> Switch to Entity</a>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<!-- More rows dynamically rendered here -->
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Company Details Modal -->
|
||||||
|
<div class="modal fade" id="companyDetailsModal" tabindex="-1" aria-labelledby="companyDetailsModalLabel" aria-hidden="true">
|
||||||
|
<div class="modal-dialog modal-lg">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header bg-light">
|
||||||
|
<h5 class="modal-title" id="companyDetailsModalLabel"><i class="bi bi-building me-2"></i>Company Details</h5>
|
||||||
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<div id="companyDetailsContent">
|
||||||
|
<!-- Company details will be loaded here -->
|
||||||
|
<div class="row mb-4">
|
||||||
|
<div class="col-md-6">
|
||||||
|
<div class="card h-100">
|
||||||
|
<div class="card-header">General Information</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<table class="table table-borderless">
|
||||||
|
<tr>
|
||||||
|
<th>Company Name:</th>
|
||||||
|
<td id="modal-company-name">Zanzibar Digital Solutions</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>Type:</th>
|
||||||
|
<td id="modal-company-type">Startup FZC</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>Registration Date:</th>
|
||||||
|
<td id="modal-registration-date">2025-04-01</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>Status:</th>
|
||||||
|
<td id="modal-status"><span class="badge bg-success">Active</span></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>Purpose:</th>
|
||||||
|
<td id="modal-purpose">Digital solutions and blockchain development</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-6">
|
||||||
|
<div class="card h-100">
|
||||||
|
<div class="card-header">Billing Information</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<table class="table table-borderless">
|
||||||
|
<tr>
|
||||||
|
<th>Plan:</th>
|
||||||
|
<td id="modal-plan">Startup FZC - $50/month</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>Next Billing:</th>
|
||||||
|
<td id="modal-next-billing">2025-06-01</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>Payment Method:</th>
|
||||||
|
<td id="modal-payment-method">Credit Card (****4582)</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row mb-4">
|
||||||
|
<div class="col-md-6">
|
||||||
|
<div class="card h-100">
|
||||||
|
<div class="card-header">Shareholders</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<table class="table table-sm">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Name</th>
|
||||||
|
<th>Percentage</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody id="modal-shareholders">
|
||||||
|
<tr>
|
||||||
|
<td>John Smith</td>
|
||||||
|
<td>60%</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Sarah Johnson</td>
|
||||||
|
<td>40%</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-6">
|
||||||
|
<div class="card h-100">
|
||||||
|
<div class="card-header">Contracts</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<table class="table table-sm">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Contract</th>
|
||||||
|
<th>Status</th>
|
||||||
|
<th>Action</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody id="modal-contracts">
|
||||||
|
<tr>
|
||||||
|
<td>Articles of Incorporation</td>
|
||||||
|
<td><span class="badge bg-success">Signed</span></td>
|
||||||
|
<td><button class="btn btn-sm btn-outline-primary">View</button></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Terms & Conditions</td>
|
||||||
|
<td><span class="badge bg-success">Signed</span></td>
|
||||||
|
<td><button class="btn btn-sm btn-outline-primary">View</button></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Digital Asset Issuance</td>
|
||||||
|
<td><span class="badge bg-success">Signed</span></td>
|
||||||
|
<td><button class="btn btn-sm btn-outline-primary">View</button></td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
|
||||||
|
<button type="button" class="btn btn-primary" onclick="switchToEntityFromModal()"><i class="bi bi-box-arrow-in-right me-1"></i>Switch to Entity</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
1196
actix_mvc_app/src/views/company/register.html
Normal file
1196
actix_mvc_app/src/views/company/register.html
Normal file
File diff suppressed because it is too large
Load Diff
21
actix_mvc_app/src/views/company/tabs.html
Normal file
21
actix_mvc_app/src/views/company/tabs.html
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
|
||||||
|
<ul class="nav nav-tabs" id="companyTabs" role="tablist">
|
||||||
|
<li class="nav-item" role="presentation">
|
||||||
|
<button class="nav-link active" id="manage-tab" data-bs-toggle="tab" data-bs-target="#manage" type="button" role="tab" aria-controls="manage" aria-selected="true">
|
||||||
|
<i class="bi bi-building me-1"></i> Manage Companies
|
||||||
|
</button>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item" role="presentation">
|
||||||
|
<button class="nav-link" id="register-tab" data-bs-toggle="tab" data-bs-target="#register" type="button" role="tab" aria-controls="register" aria-selected="false">
|
||||||
|
<i class="bi bi-file-earmark-plus me-1"></i> Register New Company
|
||||||
|
</button>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<div class="tab-content mt-4" id="companyTabsContent">
|
||||||
|
<div class="tab-pane fade show active" id="manage" role="tabpanel" aria-labelledby="manage-tab">
|
||||||
|
{% include "company/manage.html" %}
|
||||||
|
</div>
|
||||||
|
<div class="tab-pane fade" id="register" role="tabpanel" aria-labelledby="register-tab">
|
||||||
|
{% include "company/register.html" %}
|
||||||
|
</div>
|
||||||
|
</div>
|
177
actix_mvc_app/src/views/company/view.html
Normal file
177
actix_mvc_app/src/views/company/view.html
Normal file
@ -0,0 +1,177 @@
|
|||||||
|
{% extends "base.html" %}
|
||||||
|
|
||||||
|
{% block title %}{{ company_name }} - Company Details{% endblock %}
|
||||||
|
|
||||||
|
{% block head %}
|
||||||
|
{{ super() }}
|
||||||
|
<style>
|
||||||
|
.badge-signed {
|
||||||
|
background-color: #198754;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
.badge-pending {
|
||||||
|
background-color: #ffc107;
|
||||||
|
color: #212529;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<div class="container-fluid py-4">
|
||||||
|
<div class="d-flex justify-content-between align-items-center mb-4">
|
||||||
|
<h2><i class="bi bi-building me-2"></i>{{ company_name }}</h2>
|
||||||
|
<div>
|
||||||
|
<a href="/company" class="btn btn-outline-secondary me-2"><i class="bi bi-arrow-left me-1"></i>Back to Companies</a>
|
||||||
|
<a href="/company/switch/{{ company_id }}" class="btn btn-primary"><i class="bi bi-box-arrow-in-right me-1"></i>Switch to Entity</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row mb-4">
|
||||||
|
<div class="col-md-6">
|
||||||
|
<div class="card h-100">
|
||||||
|
<div class="card-header bg-light">
|
||||||
|
<h5 class="mb-0"><i class="bi bi-info-circle me-2"></i>General Information</h5>
|
||||||
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<table class="table table-borderless">
|
||||||
|
<tr>
|
||||||
|
<th style="width: 30%">Company Name:</th>
|
||||||
|
<td>{{ company_name }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>Type:</th>
|
||||||
|
<td>{{ company_type }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>Registration Date:</th>
|
||||||
|
<td>{{ registration_date }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>Status:</th>
|
||||||
|
<td>
|
||||||
|
{% if status == "Active" %}
|
||||||
|
<span class="badge bg-success">{{ status }}</span>
|
||||||
|
{% else %}
|
||||||
|
<span class="badge bg-warning text-dark">{{ status }}</span>
|
||||||
|
{% endif %}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>Purpose:</th>
|
||||||
|
<td>{{ purpose }}</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-6">
|
||||||
|
<div class="card h-100">
|
||||||
|
<div class="card-header bg-light">
|
||||||
|
<h5 class="mb-0"><i class="bi bi-credit-card me-2"></i>Billing Information</h5>
|
||||||
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<table class="table table-borderless">
|
||||||
|
<tr>
|
||||||
|
<th style="width: 30%">Plan:</th>
|
||||||
|
<td>{{ plan }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>Next Billing:</th>
|
||||||
|
<td>{{ next_billing }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th>Payment Method:</th>
|
||||||
|
<td>{{ payment_method }}</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row mb-4">
|
||||||
|
<div class="col-md-6">
|
||||||
|
<div class="card h-100">
|
||||||
|
<div class="card-header bg-light">
|
||||||
|
<h5 class="mb-0"><i class="bi bi-people me-2"></i>Shareholders</h5>
|
||||||
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<table class="table table-striped">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Name</th>
|
||||||
|
<th>Percentage</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{% for shareholder in shareholders %}
|
||||||
|
<tr>
|
||||||
|
<td>{{ shareholder.0 }}</td>
|
||||||
|
<td>{{ shareholder.1 }}</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-6">
|
||||||
|
<div class="card h-100">
|
||||||
|
<div class="card-header bg-light">
|
||||||
|
<h5 class="mb-0"><i class="bi bi-file-earmark-text me-2"></i>Contracts</h5>
|
||||||
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<table class="table table-striped">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Contract</th>
|
||||||
|
<th>Status</th>
|
||||||
|
<th>Action</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{% for contract in contracts %}
|
||||||
|
<tr>
|
||||||
|
<td>{{ contract.0 }}</td>
|
||||||
|
<td>
|
||||||
|
{% if contract.1 == "Signed" %}
|
||||||
|
<span class="badge bg-success">{{ contract.1 }}</span>
|
||||||
|
{% else %}
|
||||||
|
<span class="badge bg-warning text-dark">{{ contract.1 }}</span>
|
||||||
|
{% endif %}
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<a href="/contracts/view/{{ contract.0 | lower | replace(from=' ', to='-') }}" class="btn btn-sm btn-outline-primary">View</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="card mb-4">
|
||||||
|
<div class="card-header bg-light">
|
||||||
|
<h5 class="mb-0"><i class="bi bi-gear me-2"></i>Actions</h5>
|
||||||
|
</div>
|
||||||
|
<div class="card-body">
|
||||||
|
<div class="d-flex gap-2">
|
||||||
|
<a href="/company/edit/{{ company_id }}" class="btn btn-outline-primary"><i class="bi bi-pencil me-1"></i>Edit Company</a>
|
||||||
|
<a href="/company/documents/{{ company_id }}" class="btn btn-outline-secondary"><i class="bi bi-file-earmark me-1"></i>Manage Documents</a>
|
||||||
|
<a href="/company/switch/{{ company_id }}" class="btn btn-primary"><i class="bi bi-box-arrow-in-right me-1"></i>Switch to Entity</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block scripts %}
|
||||||
|
{{ super() }}
|
||||||
|
<script>
|
||||||
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
|
console.log('Company view page loaded');
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
{% endblock %}
|
@ -24,11 +24,11 @@
|
|||||||
<option value="" selected disabled>Choose an asset</option>
|
<option value="" selected disabled>Choose an asset</option>
|
||||||
<!-- Tokens -->
|
<!-- Tokens -->
|
||||||
<optgroup label="Tokens">
|
<optgroup label="Tokens">
|
||||||
<option value="TFT" data-type="token" data-value="5000" data-amount="10000" data-unit="TFT" data-img="/static/img/tokens/tft.png">
|
<option value="TFT" data-type="token" data-value="5000" data-amount="10000" data-unit="TFT">
|
||||||
ThreeFold Token (TFT) - 10,000 TFT ($5,000)
|
<i class="bi bi-coin me-2" style="font-size: 1.5rem;"></i> ThreeFold Token (TFT) - 10,000 TFT ($5,000)
|
||||||
</option>
|
</option>
|
||||||
<option value="ZDFZ" data-type="token" data-value="2500" data-amount="5000" data-unit="ZDFZ" data-img="/static/img/tokens/zdfz.png">
|
<option value="ZDFZ" data-type="token" data-value="2500" data-amount="5000" data-unit="ZDFZ">
|
||||||
Zanzibar Token (ZDFZ) - 5,000 ZDFZ ($2,500)
|
<i class="bi bi-coin me-2" style="font-size: 1.5rem;"></i> Zanzibar Token (ZDFZ) - 5,000 ZDFZ ($2,500)
|
||||||
</option>
|
</option>
|
||||||
</optgroup>
|
</optgroup>
|
||||||
<!-- Digital Assets -->
|
<!-- Digital Assets -->
|
||||||
@ -180,7 +180,7 @@
|
|||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
<div class="d-flex align-items-center">
|
<div class="d-flex align-items-center">
|
||||||
<img src="/static/img/tokens/tft.png" alt="TFT" width="20" height="20" class="rounded-circle me-1">
|
<i class="bi bi-coin me-2" style="font-size: 1.5rem;"></i>
|
||||||
2,000 TFT
|
2,000 TFT
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
@ -232,7 +232,7 @@
|
|||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
<div class="d-flex align-items-center">
|
<div class="d-flex align-items-center">
|
||||||
<img src="/static/img/tokens/zdfz.png" alt="ZDFZ" width="20" height="20" class="rounded-circle me-1">
|
<i class="bi bi-coin me-2" style="font-size: 1.5rem;"></i>
|
||||||
1,000 ZDFZ
|
1,000 ZDFZ
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
|
@ -179,7 +179,7 @@
|
|||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
<div class="d-flex align-items-center">
|
<div class="d-flex align-items-center">
|
||||||
<div class="token-icon me-2"></div>
|
<i class="bi bi-coin me-2" style="font-size: 1.5rem;"></i>
|
||||||
{{ position.base.asset_name }}
|
{{ position.base.asset_name }}
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
@ -232,14 +232,14 @@
|
|||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
<div class="d-flex align-items-center">
|
<div class="d-flex align-items-center">
|
||||||
<div class="token-icon me-2"></div>
|
<i class="bi bi-coin me-2" style="font-size: 1.5rem;"></i>
|
||||||
{{ position.base.asset_name }}
|
{{ position.base.asset_name }}
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td>{{ position.base.amount }} {{ position.base.asset_symbol }}</td>
|
<td>{{ position.base.amount }} {{ position.base.asset_symbol }}</td>
|
||||||
<td>
|
<td>
|
||||||
<div class="d-flex align-items-center">
|
<div class="d-flex align-items-center">
|
||||||
<div class="token-icon me-2"></div>
|
<i class="bi bi-coin me-2" style="font-size: 1.5rem;"></i>
|
||||||
{{ position.collateral_amount }} {{ position.collateral_asset_symbol }}
|
{{ position.collateral_amount }} {{ position.collateral_asset_symbol }}
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
|
@ -34,8 +34,8 @@
|
|||||||
<td>
|
<td>
|
||||||
<div class="d-flex align-items-center">
|
<div class="d-flex align-items-center">
|
||||||
<div class="position-relative me-2">
|
<div class="position-relative me-2">
|
||||||
<img src="/static/img/tokens/tft.png" alt="TFT" width="24" height="24" class="rounded-circle">
|
|
||||||
<img src="/static/img/tokens/zdfz.png" alt="ZDFZ" width="24" height="24" class="rounded-circle position-absolute" style="left: 15px; top: 0;">
|
|
||||||
</div>
|
</div>
|
||||||
TFT-ZDFZ
|
TFT-ZDFZ
|
||||||
</div>
|
</div>
|
||||||
@ -56,8 +56,8 @@
|
|||||||
<td>
|
<td>
|
||||||
<div class="d-flex align-items-center">
|
<div class="d-flex align-items-center">
|
||||||
<div class="position-relative me-2">
|
<div class="position-relative me-2">
|
||||||
<img src="/static/img/tokens/tft.png" alt="TFT" width="24" height="24" class="rounded-circle">
|
|
||||||
<img src="/static/img/tokens/usdt.png" alt="USDT" width="24" height="24" class="rounded-circle position-absolute" style="left: 15px; top: 0;">
|
|
||||||
</div>
|
</div>
|
||||||
TFT-USDT
|
TFT-USDT
|
||||||
</div>
|
</div>
|
||||||
@ -76,13 +76,7 @@
|
|||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
<div class="d-flex align-items-center">
|
ZDFZ-USDT
|
||||||
<div class="position-relative me-2">
|
|
||||||
<img src="/static/img/tokens/zdfz.png" alt="ZDFZ" width="24" height="24" class="rounded-circle">
|
|
||||||
<img src="/static/img/tokens/usdt.png" alt="USDT" width="24" height="24" class="rounded-circle position-absolute" style="left: 15px; top: 0;">
|
|
||||||
</div>
|
|
||||||
ZDFZ-USDT
|
|
||||||
</div>
|
|
||||||
</td>
|
</td>
|
||||||
<td>$850,000</td>
|
<td>$850,000</td>
|
||||||
<td>$32,000</td>
|
<td>$32,000</td>
|
||||||
@ -117,13 +111,7 @@
|
|||||||
<div class="col-md-6 col-lg-4 mb-4">
|
<div class="col-md-6 col-lg-4 mb-4">
|
||||||
<div class="card h-100">
|
<div class="card h-100">
|
||||||
<div class="card-header bg-light">
|
<div class="card-header bg-light">
|
||||||
<div class="d-flex align-items-center">
|
TFT-ZDFZ
|
||||||
<div class="position-relative me-2">
|
|
||||||
<img src="/static/img/tokens/tft.png" alt="TFT" width="24" height="24" class="rounded-circle">
|
|
||||||
<img src="/static/img/tokens/zdfz.png" alt="ZDFZ" width="24" height="24" class="rounded-circle position-absolute" style="left: 15px; top: 0;">
|
|
||||||
</div>
|
|
||||||
TFT-ZDFZ
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<div class="d-flex justify-content-between mb-2">
|
<div class="d-flex justify-content-between mb-2">
|
||||||
@ -163,13 +151,7 @@
|
|||||||
<div class="col-md-6 col-lg-4 mb-4">
|
<div class="col-md-6 col-lg-4 mb-4">
|
||||||
<div class="card h-100">
|
<div class="card h-100">
|
||||||
<div class="card-header bg-light">
|
<div class="card-header bg-light">
|
||||||
<div class="d-flex align-items-center">
|
ZDFZ-USDT
|
||||||
<div class="position-relative me-2">
|
|
||||||
<img src="/static/img/tokens/zdfz.png" alt="ZDFZ" width="24" height="24" class="rounded-circle">
|
|
||||||
<img src="/static/img/tokens/usdt.png" alt="USDT" width="24" height="24" class="rounded-circle position-absolute" style="left: 15px; top: 0;">
|
|
||||||
</div>
|
|
||||||
ZDFZ-USDT
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<div class="d-flex justify-content-between mb-2">
|
<div class="d-flex justify-content-between mb-2">
|
||||||
|
@ -156,7 +156,7 @@ This is a compliant version of the previous lending_borrowing.html tab. All term
|
|||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
<div class="d-flex align-items-center">
|
<div class="d-flex align-items-center">
|
||||||
<div class="token-icon me-2"></div>
|
<i class="bi bi-coin me-2" style="font-size: 1.5rem;"></i>
|
||||||
{{ position.base.asset_name }}
|
{{ position.base.asset_name }}
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
@ -211,16 +211,13 @@ This is a compliant version of the previous lending_borrowing.html tab. All term
|
|||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
<div class="d-flex align-items-center">
|
<div class="d-flex align-items-center">
|
||||||
<div class="token-icon me-2"></div>
|
<i class="bi bi-coin me-2" style="font-size: 1.5rem;"></i>
|
||||||
{{ position.base.asset_name }}
|
{{ position.base.asset_name }}
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td>{{ position.base.amount }} {{ position.base.asset_symbol }}</td>
|
<td>{{ position.base.amount }} {{ position.base.asset_symbol }}</td>
|
||||||
<td>
|
<td>
|
||||||
<div class="d-flex align-items-center">
|
{{ position.collateral_amount }} {{ position.collateral_asset_symbol }}
|
||||||
<div class="token-icon me-2"></div>
|
|
||||||
{{ position.collateral_amount }} {{ position.collateral_asset_symbol }}
|
|
||||||
</div>
|
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<div class="d-flex align-items-center">
|
<div class="d-flex align-items-center">
|
||||||
|
@ -22,7 +22,6 @@
|
|||||||
<div class="card h-100">
|
<div class="card h-100">
|
||||||
<div class="card-header bg-primary text-white">
|
<div class="card-header bg-primary text-white">
|
||||||
<div class="d-flex align-items-center">
|
<div class="d-flex align-items-center">
|
||||||
<img src="/static/img/tokens/tft.png" alt="TFT" width="24" height="24" class="rounded-circle me-2">
|
|
||||||
<h6 class="mb-0">ThreeFold Token (TFT)</h6>
|
<h6 class="mb-0">ThreeFold Token (TFT)</h6>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -80,7 +79,6 @@
|
|||||||
<div class="card h-100">
|
<div class="card h-100">
|
||||||
<div class="card-header bg-success text-white">
|
<div class="card-header bg-success text-white">
|
||||||
<div class="d-flex align-items-center">
|
<div class="d-flex align-items-center">
|
||||||
<img src="/static/img/tokens/zdfz.png" alt="ZDFZ" width="24" height="24" class="rounded-circle me-2">
|
|
||||||
<h6 class="mb-0">Zanzibar Token (ZDFZ)</h6>
|
<h6 class="mb-0">Zanzibar Token (ZDFZ)</h6>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -221,7 +219,7 @@
|
|||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
<div class="d-flex align-items-center">
|
<div class="d-flex align-items-center">
|
||||||
<img src="/static/img/tokens/tft.png" alt="TFT" width="24" height="24" class="rounded-circle me-2">
|
<i class="bi bi-coin me-2" style="font-size: 1.5rem;"></i>
|
||||||
ThreeFold Token (TFT)
|
ThreeFold Token (TFT)
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
@ -239,7 +237,7 @@
|
|||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
<div class="d-flex align-items-center">
|
<div class="d-flex align-items-center">
|
||||||
<img src="/static/img/tokens/zdfz.png" alt="ZDFZ" width="24" height="24" class="rounded-circle me-2">
|
<i class="bi bi-coin me-2" style="font-size: 1.5rem;"></i>
|
||||||
Zanzibar Token (ZDFZ)
|
Zanzibar Token (ZDFZ)
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
|
@ -29,27 +29,26 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="dropdown">
|
<div class="dropdown">
|
||||||
<button class="btn btn-outline-primary dropdown-toggle d-flex align-items-center" type="button" id="fromTokenDropdown" data-bs-toggle="dropdown" aria-expanded="false">
|
<button class="btn btn-outline-primary dropdown-toggle d-flex align-items-center" type="button" id="fromTokenDropdown" data-bs-toggle="dropdown" aria-expanded="false">
|
||||||
<img src="/static/img/tokens/tft.png" alt="TFT" width="24" height="24" class="rounded-circle me-2" id="fromTokenImg">
|
|
||||||
<span id="fromTokenSymbol">TFT</span>
|
<span id="fromTokenSymbol">TFT</span>
|
||||||
</button>
|
</button>
|
||||||
<input type="hidden" name="from_token" id="fromTokenInput" value="TFT">
|
<input type="hidden" name="from_token" id="fromTokenInput" value="TFT">
|
||||||
<ul class="dropdown-menu" aria-labelledby="fromTokenDropdown">
|
<ul class="dropdown-menu" aria-labelledby="fromTokenDropdown">
|
||||||
<li><a class="dropdown-item d-flex align-items-center" href="#" data-token="TFT" data-img="/static/img/tokens/tft.png" data-balance="10000">
|
<li><a class="dropdown-item d-flex align-items-center" href="#" data-token="TFT" data-balance="10000">
|
||||||
<img src="/static/img/tokens/tft.png" alt="TFT" width="24" height="24" class="rounded-circle me-2">
|
|
||||||
<div>
|
<div>
|
||||||
<div>ThreeFold Token</div>
|
<div>ThreeFold Token</div>
|
||||||
<small class="text-muted">Balance: 10,000 TFT</small>
|
<small class="text-muted">Balance: 10,000 TFT</small>
|
||||||
</div>
|
</div>
|
||||||
</a></li>
|
</a></li>
|
||||||
<li><a class="dropdown-item d-flex align-items-center" href="#" data-token="ZDFZ" data-img="/static/img/tokens/zdfz.png" data-balance="5000">
|
<li><a class="dropdown-item d-flex align-items-center" href="#" data-token="ZDFZ" data-img="/static/img/tokens/zdfz.png" data-balance="5000">
|
||||||
<img src="/static/img/tokens/zdfz.png" alt="ZDFZ" width="24" height="24" class="rounded-circle me-2">
|
|
||||||
<div>
|
<div>
|
||||||
<div>Zanzibar Token</div>
|
<div>Zanzibar Token</div>
|
||||||
<small class="text-muted">Balance: 5,000 ZDFZ</small>
|
<small class="text-muted">Balance: 5,000 ZDFZ</small>
|
||||||
</div>
|
</div>
|
||||||
</a></li>
|
</a></li>
|
||||||
<li><a class="dropdown-item d-flex align-items-center" href="#" data-token="USDT" data-img="/static/img/tokens/usdt.png" data-balance="2500">
|
<li><a class="dropdown-item d-flex align-items-center" href="#" data-token="USDT" data-img="/static/img/tokens/usdt.png" data-balance="2500">
|
||||||
<img src="/static/img/tokens/usdt.png" alt="USDT" width="24" height="24" class="rounded-circle me-2">
|
|
||||||
<div>
|
<div>
|
||||||
<div>Tether USD</div>
|
<div>Tether USD</div>
|
||||||
<small class="text-muted">Balance: 2,500 USDT</small>
|
<small class="text-muted">Balance: 2,500 USDT</small>
|
||||||
@ -82,21 +81,21 @@
|
|||||||
<input type="number" class="form-control form-control-lg border-0" id="swapToAmount" name="to_amount" placeholder="0.0" readonly>
|
<input type="number" class="form-control form-control-lg border-0" id="swapToAmount" name="to_amount" placeholder="0.0" readonly>
|
||||||
<div class="dropdown">
|
<div class="dropdown">
|
||||||
<button class="btn btn-outline-primary dropdown-toggle d-flex align-items-center" type="button" id="toTokenDropdown" data-bs-toggle="dropdown" aria-expanded="false">
|
<button class="btn btn-outline-primary dropdown-toggle d-flex align-items-center" type="button" id="toTokenDropdown" data-bs-toggle="dropdown" aria-expanded="false">
|
||||||
<img src="/static/img/tokens/zdfz.png" alt="ZDFZ" width="24" height="24" class="rounded-circle me-2" id="toTokenImg">
|
<i class="bi bi-coin me-2" style="font-size: 1.5rem;"></i>
|
||||||
<span id="toTokenSymbol">ZDFZ</span>
|
<span id="toTokenSymbol">ZDFZ</span>
|
||||||
</button>
|
</button>
|
||||||
<input type="hidden" name="to_token" id="toTokenInput" value="ZDFZ">
|
<input type="hidden" name="to_token" id="toTokenInput" value="ZDFZ">
|
||||||
<ul class="dropdown-menu" aria-labelledby="toTokenDropdown">
|
<ul class="dropdown-menu" aria-labelledby="toTokenDropdown">
|
||||||
<li><a class="dropdown-item d-flex align-items-center" href="#" data-token="TFT" data-img="/static/img/tokens/tft.png">
|
<li><a class="dropdown-item d-flex align-items-center" href="#" data-token="TFT" data-img="/static/img/tokens/tft.png">
|
||||||
<img src="/static/img/tokens/tft.png" alt="TFT" width="24" height="24" class="rounded-circle me-2">
|
|
||||||
<div>ThreeFold Token</div>
|
<div>ThreeFold Token</div>
|
||||||
</a></li>
|
</a></li>
|
||||||
<li><a class="dropdown-item d-flex align-items-center" href="#" data-token="ZDFZ" data-img="/static/img/tokens/zdfz.png">
|
<li><a class="dropdown-item d-flex align-items-center" href="#" data-token="ZDFZ" data-img="/static/img/tokens/zdfz.png">
|
||||||
<img src="/static/img/tokens/zdfz.png" alt="ZDFZ" width="24" height="24" class="rounded-circle me-2">
|
|
||||||
<div>Zanzibar Token</div>
|
<div>Zanzibar Token</div>
|
||||||
</a></li>
|
</a></li>
|
||||||
<li><a class="dropdown-item d-flex align-items-center" href="#" data-token="USDT" data-img="/static/img/tokens/usdt.png">
|
<li><a class="dropdown-item d-flex align-items-center" href="#" data-token="USDT" data-img="/static/img/tokens/usdt.png">
|
||||||
<img src="/static/img/tokens/usdt.png" alt="USDT" width="24" height="24" class="rounded-circle me-2">
|
|
||||||
<div>Tether USD</div>
|
<div>Tether USD</div>
|
||||||
</a></li>
|
</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
@ -163,13 +162,13 @@
|
|||||||
<td>2025-04-15 14:32</td>
|
<td>2025-04-15 14:32</td>
|
||||||
<td>
|
<td>
|
||||||
<div class="d-flex align-items-center">
|
<div class="d-flex align-items-center">
|
||||||
<img src="/static/img/tokens/tft.png" alt="TFT" width="20" height="20" class="rounded-circle me-1">
|
|
||||||
500 TFT
|
500 TFT
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<div class="d-flex align-items-center">
|
<div class="d-flex align-items-center">
|
||||||
<img src="/static/img/tokens/zdfz.png" alt="ZDFZ" width="20" height="20" class="rounded-circle me-1">
|
|
||||||
250 ZDFZ
|
250 ZDFZ
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
@ -179,13 +178,13 @@
|
|||||||
<td>2025-04-14 09:17</td>
|
<td>2025-04-14 09:17</td>
|
||||||
<td>
|
<td>
|
||||||
<div class="d-flex align-items-center">
|
<div class="d-flex align-items-center">
|
||||||
<img src="/static/img/tokens/usdt.png" alt="USDT" width="20" height="20" class="rounded-circle me-1">
|
<i class="bi bi-coin me-2" style="font-size: 1.5rem;"></i>
|
||||||
1,000 USDT
|
1,000 USDT
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<div class="d-flex align-items-center">
|
<div class="d-flex align-items-center">
|
||||||
<img src="/static/img/tokens/tft.png" alt="TFT" width="20" height="20" class="rounded-circle me-1">
|
<i class="bi bi-coin me-2" style="font-size: 1.5rem;"></i>
|
||||||
2,000 TFT
|
2,000 TFT
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
@ -195,13 +194,13 @@
|
|||||||
<td>2025-04-12 16:45</td>
|
<td>2025-04-12 16:45</td>
|
||||||
<td>
|
<td>
|
||||||
<div class="d-flex align-items-center">
|
<div class="d-flex align-items-center">
|
||||||
<img src="/static/img/tokens/zdfz.png" alt="ZDFZ" width="20" height="20" class="rounded-circle me-1">
|
<i class="bi bi-coin me-2" style="font-size: 1.5rem;"></i>
|
||||||
100 ZDFZ
|
100 ZDFZ
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<div class="d-flex align-items-center">
|
<div class="d-flex align-items-center">
|
||||||
<img src="/static/img/tokens/usdt.png" alt="USDT" width="20" height="20" class="rounded-circle me-1">
|
<i class="bi bi-coin me-2" style="font-size: 1.5rem;"></i>
|
||||||
50 USDT
|
50 USDT
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
@ -234,8 +233,8 @@
|
|||||||
<td>
|
<td>
|
||||||
<div class="d-flex align-items-center">
|
<div class="d-flex align-items-center">
|
||||||
<div class="position-relative me-2">
|
<div class="position-relative me-2">
|
||||||
<img src="/static/img/tokens/tft.png" alt="TFT" width="20" height="20" class="rounded-circle">
|
<i class="bi bi-coin me-2" style="font-size: 1.5rem;"></i>
|
||||||
<img src="/static/img/tokens/zdfz.png" alt="ZDFZ" width="20" height="20" class="rounded-circle position-absolute" style="left: 10px; top: 0;">
|
<i class="bi bi-coin me-2" style="font-size: 1.5rem;"></i>
|
||||||
</div>
|
</div>
|
||||||
TFT/ZDFZ
|
TFT/ZDFZ
|
||||||
</div>
|
</div>
|
||||||
@ -248,8 +247,8 @@
|
|||||||
<td>
|
<td>
|
||||||
<div class="d-flex align-items-center">
|
<div class="d-flex align-items-center">
|
||||||
<div class="position-relative me-2">
|
<div class="position-relative me-2">
|
||||||
<img src="/static/img/tokens/tft.png" alt="TFT" width="20" height="20" class="rounded-circle">
|
<i class="bi bi-coin me-2" style="font-size: 1.5rem;"></i>
|
||||||
<img src="/static/img/tokens/usdt.png" alt="USDT" width="20" height="20" class="rounded-circle position-absolute" style="left: 10px; top: 0;">
|
<i class="bi bi-coin me-2" style="font-size: 1.5rem;"></i>
|
||||||
</div>
|
</div>
|
||||||
TFT/USDT
|
TFT/USDT
|
||||||
</div>
|
</div>
|
||||||
@ -262,8 +261,8 @@
|
|||||||
<td>
|
<td>
|
||||||
<div class="d-flex align-items-center">
|
<div class="d-flex align-items-center">
|
||||||
<div class="position-relative me-2">
|
<div class="position-relative me-2">
|
||||||
<img src="/static/img/tokens/zdfz.png" alt="ZDFZ" width="20" height="20" class="rounded-circle">
|
<i class="bi bi-coin me-2" style="font-size: 1.5rem;"></i>
|
||||||
<img src="/static/img/tokens/usdt.png" alt="USDT" width="20" height="20" class="rounded-circle position-absolute" style="left: 10px; top: 0;">
|
<i class="bi bi-coin me-2" style="font-size: 1.5rem;"></i>
|
||||||
</div>
|
</div>
|
||||||
ZDFZ/USDT
|
ZDFZ/USDT
|
||||||
</div>
|
</div>
|
||||||
|
173
actix_mvc_app/static/js/company.js
Normal file
173
actix_mvc_app/static/js/company.js
Normal file
@ -0,0 +1,173 @@
|
|||||||
|
// Company data (would be loaded from backend in production)
|
||||||
|
var companyData = {
|
||||||
|
'company1': {
|
||||||
|
name: 'Zanzibar Digital Solutions',
|
||||||
|
type: 'Startup FZC',
|
||||||
|
status: 'Active',
|
||||||
|
registrationDate: '2025-04-01',
|
||||||
|
purpose: 'Digital solutions and blockchain development',
|
||||||
|
plan: 'Startup FZC - $50/month',
|
||||||
|
nextBilling: '2025-06-01',
|
||||||
|
paymentMethod: 'Credit Card (****4582)',
|
||||||
|
shareholders: [
|
||||||
|
{ name: 'John Smith', percentage: '60%' },
|
||||||
|
{ name: 'Sarah Johnson', percentage: '40%' }
|
||||||
|
],
|
||||||
|
contracts: [
|
||||||
|
{ name: 'Articles of Incorporation', status: 'Signed' },
|
||||||
|
{ name: 'Terms & Conditions', status: 'Signed' },
|
||||||
|
{ name: 'Digital Asset Issuance', status: 'Signed' }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
'company2': {
|
||||||
|
name: 'Blockchain Innovations Ltd',
|
||||||
|
type: 'Growth FZC',
|
||||||
|
status: 'Active',
|
||||||
|
registrationDate: '2025-03-15',
|
||||||
|
purpose: 'Blockchain technology research and development',
|
||||||
|
plan: 'Growth FZC - $100/month',
|
||||||
|
nextBilling: '2025-06-15',
|
||||||
|
paymentMethod: 'Bank Transfer',
|
||||||
|
shareholders: [
|
||||||
|
{ name: 'Michael Chen', percentage: '35%' },
|
||||||
|
{ name: 'Aisha Patel', percentage: '35%' },
|
||||||
|
{ name: 'David Okonkwo', percentage: '30%' }
|
||||||
|
],
|
||||||
|
contracts: [
|
||||||
|
{ name: 'Articles of Incorporation', status: 'Signed' },
|
||||||
|
{ name: 'Terms & Conditions', status: 'Signed' },
|
||||||
|
{ name: 'Digital Asset Issuance', status: 'Signed' },
|
||||||
|
{ name: 'Physical Asset Holding', status: 'Signed' }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
'company3': {
|
||||||
|
name: 'Sustainable Energy Cooperative',
|
||||||
|
type: 'Cooperative FZC',
|
||||||
|
status: 'Pending',
|
||||||
|
registrationDate: '2025-05-01',
|
||||||
|
purpose: 'Renewable energy production and distribution',
|
||||||
|
plan: 'Cooperative FZC - $200/month',
|
||||||
|
nextBilling: 'Pending Activation',
|
||||||
|
paymentMethod: 'Pending',
|
||||||
|
shareholders: [
|
||||||
|
{ name: 'Community Energy Group', percentage: '40%' },
|
||||||
|
{ name: 'Green Future Initiative', percentage: '30%' },
|
||||||
|
{ name: 'Sustainable Living Collective', percentage: '30%' }
|
||||||
|
],
|
||||||
|
contracts: [
|
||||||
|
{ name: 'Articles of Incorporation', status: 'Signed' },
|
||||||
|
{ name: 'Terms & Conditions', status: 'Signed' },
|
||||||
|
{ name: 'Cooperative Governance', status: 'Pending' }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Current company ID for modal
|
||||||
|
var currentCompanyId = null;
|
||||||
|
|
||||||
|
// View company details function
|
||||||
|
function viewCompanyDetails(companyId) {
|
||||||
|
// Store current company ID
|
||||||
|
currentCompanyId = companyId;
|
||||||
|
|
||||||
|
// Get company data
|
||||||
|
const company = companyData[companyId];
|
||||||
|
if (!company) return;
|
||||||
|
|
||||||
|
// Update modal title
|
||||||
|
document.getElementById('companyDetailsModalLabel').innerHTML =
|
||||||
|
`<i class="bi bi-building me-2"></i>${company.name} Details`;
|
||||||
|
|
||||||
|
// Update general information
|
||||||
|
document.getElementById('modal-company-name').textContent = company.name;
|
||||||
|
document.getElementById('modal-company-type').textContent = company.type;
|
||||||
|
document.getElementById('modal-registration-date').textContent = company.registrationDate;
|
||||||
|
|
||||||
|
// Update status with appropriate badge
|
||||||
|
const statusBadge = company.status === 'Active' ?
|
||||||
|
`<span class="badge bg-success">${company.status}</span>` :
|
||||||
|
`<span class="badge bg-warning text-dark">${company.status}</span>`;
|
||||||
|
document.getElementById('modal-status').innerHTML = statusBadge;
|
||||||
|
|
||||||
|
document.getElementById('modal-purpose').textContent = company.purpose;
|
||||||
|
|
||||||
|
// Update billing information
|
||||||
|
document.getElementById('modal-plan').textContent = company.plan;
|
||||||
|
document.getElementById('modal-next-billing').textContent = company.nextBilling;
|
||||||
|
document.getElementById('modal-payment-method').textContent = company.paymentMethod;
|
||||||
|
|
||||||
|
// Update shareholders table
|
||||||
|
const shareholdersTable = document.getElementById('modal-shareholders');
|
||||||
|
shareholdersTable.innerHTML = '';
|
||||||
|
company.shareholders.forEach(shareholder => {
|
||||||
|
const row = document.createElement('tr');
|
||||||
|
row.innerHTML = `
|
||||||
|
<td>${shareholder.name}</td>
|
||||||
|
<td>${shareholder.percentage}</td>
|
||||||
|
`;
|
||||||
|
shareholdersTable.appendChild(row);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Update contracts table
|
||||||
|
const contractsTable = document.getElementById('modal-contracts');
|
||||||
|
contractsTable.innerHTML = '';
|
||||||
|
company.contracts.forEach(contract => {
|
||||||
|
const row = document.createElement('tr');
|
||||||
|
const statusBadge = contract.status === 'Signed' ?
|
||||||
|
`<span class="badge bg-success">${contract.status}</span>` :
|
||||||
|
`<span class="badge bg-warning text-dark">${contract.status}</span>`;
|
||||||
|
|
||||||
|
row.innerHTML = `
|
||||||
|
<td>${contract.name}</td>
|
||||||
|
<td>${statusBadge}</td>
|
||||||
|
<td><button class="btn btn-sm btn-outline-primary" onclick="viewContract('${contract.name.toLowerCase().replace(/\s+/g, '-')}')">View</button></td>
|
||||||
|
`;
|
||||||
|
contractsTable.appendChild(row);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Show the modal
|
||||||
|
const modal = new bootstrap.Modal(document.getElementById('companyDetailsModal'));
|
||||||
|
modal.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Switch to entity function
|
||||||
|
function switchToEntity(companyId) {
|
||||||
|
const company = companyData[companyId];
|
||||||
|
if (!company) return;
|
||||||
|
|
||||||
|
// In a real application, this would redirect to the entity context
|
||||||
|
// For now, we'll just show an alert
|
||||||
|
alert(`Switching to ${company.name} entity context. All UI will now reflect this entity's governance, billing, and other features.`);
|
||||||
|
|
||||||
|
// This would typically involve:
|
||||||
|
// 1. Setting a session/cookie for the current entity
|
||||||
|
// 2. Redirecting to the dashboard with that entity context
|
||||||
|
// window.location.href = `/dashboard?entity=${companyId}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Switch to entity from modal
|
||||||
|
function switchToEntityFromModal() {
|
||||||
|
if (currentCompanyId) {
|
||||||
|
switchToEntity(currentCompanyId);
|
||||||
|
// Close the modal
|
||||||
|
const modal = bootstrap.Modal.getInstance(document.getElementById('companyDetailsModal'));
|
||||||
|
modal.hide();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// View contract function
|
||||||
|
function viewContract(contractId) {
|
||||||
|
// In a real application, this would open the contract document
|
||||||
|
// For now, we'll just show an alert
|
||||||
|
alert(`Viewing contract: ${contractId.replace(/-/g, ' ')}`);
|
||||||
|
|
||||||
|
// This would typically involve:
|
||||||
|
// 1. Fetching the contract document from the server
|
||||||
|
// 2. Opening it in a viewer or new tab
|
||||||
|
// window.open(`/contracts/view/${contractId}`, '_blank');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize when DOM is loaded
|
||||||
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
|
console.log('Company management script loaded');
|
||||||
|
});
|
@ -411,18 +411,9 @@ document.addEventListener('DOMContentLoaded', function() {
|
|||||||
if (liquidationUnitElement) liquidationUnitElement.textContent = assetUnit;
|
if (liquidationUnitElement) liquidationUnitElement.textContent = assetUnit;
|
||||||
|
|
||||||
// Calculate collateral value
|
// Calculate collateral value
|
||||||
const amount = parseFloat(collateralAmountInput.value) || 0;
|
|
||||||
let collateralValue = 0;
|
|
||||||
|
|
||||||
if (assetType === 'token') {
|
|
||||||
// For tokens, calculate based on token price
|
|
||||||
const tokenPrice = assetValue / assetAmount;
|
|
||||||
collateralValue = amount * tokenPrice;
|
|
||||||
} else {
|
} else {
|
||||||
// For NFTs and other assets, use the full value if amount is 1
|
liquidationPriceElement.value = (borrowedValue * 1.2).toFixed(2);
|
||||||
collateralValue = amount === 1 ? assetValue : 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (collateralValueElement) collateralValueElement.value = collateralValue.toFixed(2);
|
if (collateralValueElement) collateralValueElement.value = collateralValue.toFixed(2);
|
||||||
|
|
||||||
// Calculate max loan amount (75% of collateral value)
|
// Calculate max loan amount (75% of collateral value)
|
||||||
|
Loading…
Reference in New Issue
Block a user