From 9468595395435bad1c8779287784999d62f69275 Mon Sep 17 00:00:00 2001 From: timurgordon Date: Mon, 5 May 2025 13:58:51 +0300 Subject: [PATCH] Add company management module with registration and entity switching --- actix_mvc_app/Cargo.lock | 151 +++ actix_mvc_app/Cargo.toml | 2 + actix_mvc_app/src/controllers/company.rs | 245 ++++ actix_mvc_app/src/controllers/mod.rs | 1 + actix_mvc_app/src/routes/mod.rs | 9 + actix_mvc_app/src/static/js/company.js | 173 +++ actix_mvc_app/src/views/base.html | 45 +- actix_mvc_app/src/views/company/index.html | 111 ++ actix_mvc_app/src/views/company/manage.html | 193 +++ actix_mvc_app/src/views/company/register.html | 1196 +++++++++++++++++ actix_mvc_app/src/views/company/tabs.html | 21 + actix_mvc_app/src/views/company/view.html | 177 +++ .../src/views/defi/tabs/collateral.html | 12 +- .../views/defi/tabs/lending_borrowing.html | 6 +- .../src/views/defi/tabs/liquidity.html | 32 +- .../views/defi/tabs/providing_receiving.html | 9 +- .../src/views/defi/tabs/staking.html | 6 +- actix_mvc_app/src/views/defi/tabs/swap.html | 41 +- actix_mvc_app/static/js/company.js | 173 +++ actix_mvc_app/static/js/defi.js | 11 +- 20 files changed, 2538 insertions(+), 76 deletions(-) create mode 100644 actix_mvc_app/src/controllers/company.rs create mode 100644 actix_mvc_app/src/static/js/company.js create mode 100644 actix_mvc_app/src/views/company/index.html create mode 100644 actix_mvc_app/src/views/company/manage.html create mode 100644 actix_mvc_app/src/views/company/register.html create mode 100644 actix_mvc_app/src/views/company/tabs.html create mode 100644 actix_mvc_app/src/views/company/view.html create mode 100644 actix_mvc_app/static/js/company.js diff --git a/actix_mvc_app/Cargo.lock b/actix_mvc_app/Cargo.lock index 3786304..169ea39 100644 --- a/actix_mvc_app/Cargo.lock +++ b/actix_mvc_app/Cargo.lock @@ -107,6 +107,45 @@ dependencies = [ "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]] name = "actix-router" version = "0.5.3" @@ -247,6 +286,7 @@ version = "0.1.0" dependencies = [ "actix-files", "actix-identity", + "actix-multipart", "actix-session", "actix-web", "bcrypt", @@ -255,6 +295,7 @@ dependencies = [ "dotenv", "env_logger", "futures", + "futures-util", "jsonwebtoken", "lazy_static", "log", @@ -823,6 +864,41 @@ dependencies = [ "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]] name = "deranged" version = "0.4.0" @@ -947,6 +1023,22 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" 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]] name = "flate2" version = "1.1.1" @@ -1397,6 +1489,12 @@ dependencies = [ "syn", ] +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + [[package]] name = "idna" version = "1.0.3" @@ -1564,6 +1662,12 @@ version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8355be11b20d696c8f18f6cc018c4e372165b1fa8126cef092399c9951984ffa" +[[package]] +name = "linux-raw-sys" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd945864f07fe9f5371a27ad7b52a172b4b499999f1d97574c9fa68373937e12" + [[package]] name = "litemap" version = "0.7.5" @@ -1760,6 +1864,12 @@ dependencies = [ "windows-targets", ] +[[package]] +name = "parse-size" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "487f2ccd1e17ce8c1bfab3a65c89525af41cfad4c8659021a1e9a2aacd73b89b" + [[package]] name = "parse-zoneinfo" version = "0.3.1" @@ -2152,6 +2262,19 @@ dependencies = [ "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]] name = "rustversion" version = "1.0.20" @@ -2217,6 +2340,15 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_plain" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ce1fc6db65a611022b23a0dec6975d63fb80a302cb3388835ff02c097258d50" +dependencies = [ + "serde", +] + [[package]] name = "serde_spanned" version = "0.6.8" @@ -2356,6 +2488,12 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + [[package]] name = "subtle" version = "2.6.1" @@ -2384,6 +2522,19 @@ dependencies = [ "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]] name = "tera" version = "1.20.0" diff --git a/actix_mvc_app/Cargo.toml b/actix_mvc_app/Cargo.toml index 2b7b348..d39207f 100644 --- a/actix_mvc_app/Cargo.toml +++ b/actix_mvc_app/Cargo.toml @@ -4,6 +4,8 @@ version = "0.1.0" edition = "2024" [dependencies] +actix-multipart = "0.6.1" +futures-util = "0.3.30" actix-web = "4.5.1" actix-files = "0.6.5" tera = "1.19.1" diff --git a/actix_mvc_app/src/controllers/company.rs b/actix_mvc_app/src/controllers/company.rs new file mode 100644 index 0000000..554d1e4 --- /dev/null +++ b/actix_mvc_app/src/controllers/company.rs @@ -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, +} + +pub struct CompanyController; + +impl CompanyController { + // Display the company management dashboard + pub async fn index(tmpl: web::Data, req: HttpRequest) -> Result { + 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, path: web::Path) -> Result { + 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) -> Result { + 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 { + 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 = 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()) + } +} diff --git a/actix_mvc_app/src/controllers/mod.rs b/actix_mvc_app/src/controllers/mod.rs index e400af3..7e06f34 100644 --- a/actix_mvc_app/src/controllers/mod.rs +++ b/actix_mvc_app/src/controllers/mod.rs @@ -9,5 +9,6 @@ pub mod contract; pub mod asset; pub mod defi; pub mod marketplace; +pub mod company; // Re-export controllers for easier imports diff --git a/actix_mvc_app/src/routes/mod.rs b/actix_mvc_app/src/routes/mod.rs index 08622e3..48cd571 100644 --- a/actix_mvc_app/src/routes/mod.rs +++ b/actix_mvc_app/src/routes/mod.rs @@ -10,6 +10,7 @@ use crate::controllers::contract::ContractController; use crate::controllers::asset::AssetController; use crate::controllers::marketplace::MarketplaceController; use crate::controllers::defi::DefiController; +use crate::controllers::company::CompanyController; use crate::middleware::JwtAuth; 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("/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 diff --git a/actix_mvc_app/src/static/js/company.js b/actix_mvc_app/src/static/js/company.js new file mode 100644 index 0000000..f42d38b --- /dev/null +++ b/actix_mvc_app/src/static/js/company.js @@ -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 = + `${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' ? + `${company.status}` : + `${company.status}`; + 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 = ` + ${shareholder.name} + ${shareholder.percentage} + `; + 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' ? + `${contract.status}` : + `${contract.status}`; + + row.innerHTML = ` + ${contract.name} + ${statusBadge} + + `; + 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'); +}); diff --git a/actix_mvc_app/src/views/base.html b/actix_mvc_app/src/views/base.html index 8332dbd..0681c7e 100644 --- a/actix_mvc_app/src/views/base.html +++ b/actix_mvc_app/src/views/base.html @@ -64,7 +64,7 @@ -
Zanzibar Digital Freezone
+
Zanzibar Digital Freezone {% if entity_name %}| {{ entity_name }}{% endif %}
+ +
+ {% if success %} + + {% endif %} + + {% if error %} + + {% endif %} +
+ @@ -214,6 +246,17 @@ document.getElementById('sidebarToggle').addEventListener('click', function() { 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); + }); + }); {% block extra_js %}{% endblock %} diff --git a/actix_mvc_app/src/views/company/index.html b/actix_mvc_app/src/views/company/index.html new file mode 100644 index 0000000..ef7ced0 --- /dev/null +++ b/actix_mvc_app/src/views/company/index.html @@ -0,0 +1,111 @@ +{% extends "base.html" %} + +{% block title %}Company Management{% endblock %} + +{% block head %} + {{ super() }} + +{% endblock %} + +{% block content %} + +{% if success_message %} +
+ +
+{% endif %} + +
+

Company & Legal Entity Management (Freezone)

+ + +
+
+ + +
+
+ {% include "company/manage.html" %} +
+
+ {% include "company/register.html" %} +
+
+
+
+
+{% endblock %} + +{% block scripts %} + {{ super() }} + + +{% endblock %} diff --git a/actix_mvc_app/src/views/company/manage.html b/actix_mvc_app/src/views/company/manage.html new file mode 100644 index 0000000..fdfaa88 --- /dev/null +++ b/actix_mvc_app/src/views/company/manage.html @@ -0,0 +1,193 @@ +
+
+ Your Companies +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
NameTypeStatusDate RegisteredActions
Zanzibar Digital SolutionsStartup FZCActive2025-04-01 + +
Blockchain Innovations LtdGrowth FZCActive2025-03-15 + +
Sustainable Energy CooperativeCooperative FZCPending2025-05-01 + +
+
+
+ + + diff --git a/actix_mvc_app/src/views/company/register.html b/actix_mvc_app/src/views/company/register.html new file mode 100644 index 0000000..63b16d3 --- /dev/null +++ b/actix_mvc_app/src/views/company/register.html @@ -0,0 +1,1196 @@ +
+
+ Register a New Company / Legal Entity +
+
+
+ +
+
Step 1 of 4
+
+ + +
+
+ 1 General Info +
+
+ 2 Company Type +
+
+ 3 Shareholders +
+
+ 4 Documents +
+
+ + +
+

General Company Information

+
+ + +
Choose a unique name for your company or entity.
+
+
+ + +
+
+ + +
+
+ +
+
+ + + + + + + + + +
+
+
+ + + diff --git a/actix_mvc_app/src/views/company/tabs.html b/actix_mvc_app/src/views/company/tabs.html new file mode 100644 index 0000000..61aff51 --- /dev/null +++ b/actix_mvc_app/src/views/company/tabs.html @@ -0,0 +1,21 @@ + + +
+
+ {% include "company/manage.html" %} +
+
+ {% include "company/register.html" %} +
+
diff --git a/actix_mvc_app/src/views/company/view.html b/actix_mvc_app/src/views/company/view.html new file mode 100644 index 0000000..b3a8d0c --- /dev/null +++ b/actix_mvc_app/src/views/company/view.html @@ -0,0 +1,177 @@ +{% extends "base.html" %} + +{% block title %}{{ company_name }} - Company Details{% endblock %} + +{% block head %} + {{ super() }} + +{% endblock %} + +{% block content %} +
+ + +
+
+
+
+
General Information
+
+
+ + + + + + + + + + + + + + + + + + + + + +
Company Name:{{ company_name }}
Type:{{ company_type }}
Registration Date:{{ registration_date }}
Status: + {% if status == "Active" %} + {{ status }} + {% else %} + {{ status }} + {% endif %} +
Purpose:{{ purpose }}
+
+
+
+
+
+
+
Billing Information
+
+
+ + + + + + + + + + + + + +
Plan:{{ plan }}
Next Billing:{{ next_billing }}
Payment Method:{{ payment_method }}
+
+
+
+
+ +
+
+
+
+
Shareholders
+
+
+ + + + + + + + + {% for shareholder in shareholders %} + + + + + {% endfor %} + +
NamePercentage
{{ shareholder.0 }}{{ shareholder.1 }}
+
+
+
+
+
+
+
Contracts
+
+
+ + + + + + + + + + {% for contract in contracts %} + + + + + + {% endfor %} + +
ContractStatusAction
{{ contract.0 }} + {% if contract.1 == "Signed" %} + {{ contract.1 }} + {% else %} + {{ contract.1 }} + {% endif %} + + View +
+
+
+
+
+ +
+
+
Actions
+
+ +
+
+{% endblock %} + +{% block scripts %} + {{ super() }} + +{% endblock %} diff --git a/actix_mvc_app/src/views/defi/tabs/collateral.html b/actix_mvc_app/src/views/defi/tabs/collateral.html index 401e75c..7d67859 100644 --- a/actix_mvc_app/src/views/defi/tabs/collateral.html +++ b/actix_mvc_app/src/views/defi/tabs/collateral.html @@ -24,11 +24,11 @@ - - @@ -180,7 +180,7 @@
- TFT + 2,000 TFT
@@ -232,7 +232,7 @@
- ZDFZ + 1,000 ZDFZ
diff --git a/actix_mvc_app/src/views/defi/tabs/lending_borrowing.html b/actix_mvc_app/src/views/defi/tabs/lending_borrowing.html index fc21d41..480f88b 100644 --- a/actix_mvc_app/src/views/defi/tabs/lending_borrowing.html +++ b/actix_mvc_app/src/views/defi/tabs/lending_borrowing.html @@ -179,7 +179,7 @@
-
+ {{ position.base.asset_name }}
@@ -232,14 +232,14 @@
-
+ {{ position.base.asset_name }}
{{ position.base.amount }} {{ position.base.asset_symbol }}
-
+ {{ position.collateral_amount }} {{ position.collateral_asset_symbol }}
diff --git a/actix_mvc_app/src/views/defi/tabs/liquidity.html b/actix_mvc_app/src/views/defi/tabs/liquidity.html index 3070cef..0895821 100644 --- a/actix_mvc_app/src/views/defi/tabs/liquidity.html +++ b/actix_mvc_app/src/views/defi/tabs/liquidity.html @@ -34,8 +34,8 @@
- TFT - ZDFZ + +
TFT-ZDFZ
@@ -56,8 +56,8 @@
- TFT - USDT + +
TFT-USDT
@@ -76,13 +76,7 @@ -
-
- ZDFZ - USDT -
- ZDFZ-USDT -
+ ZDFZ-USDT $850,000 $32,000 @@ -117,13 +111,7 @@
-
-
- TFT - ZDFZ -
- TFT-ZDFZ -
+ TFT-ZDFZ
@@ -163,13 +151,7 @@
-
-
- ZDFZ - USDT -
- ZDFZ-USDT -
+ ZDFZ-USDT
diff --git a/actix_mvc_app/src/views/defi/tabs/providing_receiving.html b/actix_mvc_app/src/views/defi/tabs/providing_receiving.html index 2d8a2a3..9e99400 100644 --- a/actix_mvc_app/src/views/defi/tabs/providing_receiving.html +++ b/actix_mvc_app/src/views/defi/tabs/providing_receiving.html @@ -156,7 +156,7 @@ This is a compliant version of the previous lending_borrowing.html tab. All term
-
+ {{ position.base.asset_name }}
@@ -211,16 +211,13 @@ This is a compliant version of the previous lending_borrowing.html tab. All term
-
+ {{ position.base.asset_name }}
{{ position.base.amount }} {{ position.base.asset_symbol }} -
-
- {{ position.collateral_amount }} {{ position.collateral_asset_symbol }} -
+ {{ position.collateral_amount }} {{ position.collateral_asset_symbol }}
diff --git a/actix_mvc_app/src/views/defi/tabs/staking.html b/actix_mvc_app/src/views/defi/tabs/staking.html index d11eb21..7552172 100644 --- a/actix_mvc_app/src/views/defi/tabs/staking.html +++ b/actix_mvc_app/src/views/defi/tabs/staking.html @@ -22,7 +22,6 @@
- TFT
ThreeFold Token (TFT)
@@ -80,7 +79,6 @@
- ZDFZ
Zanzibar Token (ZDFZ)
@@ -221,7 +219,7 @@
- TFT + ThreeFold Token (TFT)
@@ -239,7 +237,7 @@
- ZDFZ + Zanzibar Token (ZDFZ)
diff --git a/actix_mvc_app/src/views/defi/tabs/swap.html b/actix_mvc_app/src/views/defi/tabs/swap.html index 54b6edf..8336c03 100644 --- a/actix_mvc_app/src/views/defi/tabs/swap.html +++ b/actix_mvc_app/src/views/defi/tabs/swap.html @@ -29,27 +29,26 @@