add contract md folder support
This commit is contained in:
@@ -3,8 +3,10 @@ use tera::{Context, Tera};
|
||||
use chrono::{Utc, Duration};
|
||||
use serde::Deserialize;
|
||||
use serde_json::json;
|
||||
use actix_web::web::Query;
|
||||
use std::collections::HashMap;
|
||||
|
||||
use crate::models::contract::{Contract, ContractStatus, ContractType, ContractStatistics, ContractSigner, ContractRevision, SignerStatus};
|
||||
use crate::models::contract::{Contract, ContractStatus, ContractType, ContractStatistics, ContractSigner, ContractRevision, SignerStatus, TocItem};
|
||||
use crate::utils::render_template;
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
@@ -105,7 +107,11 @@ impl ContractController {
|
||||
}
|
||||
|
||||
// Display a specific contract
|
||||
pub async fn detail(tmpl: web::Data<Tera>, path: web::Path<String>) -> Result<HttpResponse, Error> {
|
||||
pub async fn detail(
|
||||
tmpl: web::Data<Tera>,
|
||||
path: web::Path<String>,
|
||||
query: Query<HashMap<String, String>>
|
||||
) -> Result<HttpResponse, Error> {
|
||||
let contract_id = path.into_inner();
|
||||
let mut context = Context::new();
|
||||
|
||||
@@ -126,9 +132,53 @@ impl ContractController {
|
||||
|
||||
// Convert contract to JSON
|
||||
let contract_json = Self::contract_to_json(contract);
|
||||
|
||||
|
||||
// Add contract to context
|
||||
context.insert("contract", &contract_json);
|
||||
|
||||
// If this contract uses multi-page markdown, load the selected section
|
||||
println!("DEBUG: content_dir = {:?}, toc = {:?}", contract.content_dir, contract.toc);
|
||||
if let (Some(content_dir), Some(toc)) = (&contract.content_dir, &contract.toc) {
|
||||
use std::fs;
|
||||
use pulldown_cmark::{Parser, Options, html};
|
||||
// Helper to flatten toc recursively
|
||||
fn flatten_toc<'a>(items: &'a Vec<TocItem>, out: &mut Vec<&'a TocItem>) {
|
||||
for item in items {
|
||||
out.push(item);
|
||||
if !item.children.is_empty() {
|
||||
flatten_toc(&item.children, out);
|
||||
}
|
||||
}
|
||||
}
|
||||
let mut flat_toc = Vec::new();
|
||||
flatten_toc(&toc, &mut flat_toc);
|
||||
let section_param = query.get("section");
|
||||
let selected_file = section_param
|
||||
.and_then(|f| flat_toc.iter().find(|item| item.file == *f).map(|item| item.file.clone()))
|
||||
.unwrap_or_else(|| flat_toc.get(0).map(|item| item.file.clone()).unwrap_or_default());
|
||||
context.insert("section", &selected_file);
|
||||
let rel_path = format!("{}/{}", content_dir, selected_file);
|
||||
let abs_path = match std::env::current_dir() {
|
||||
Ok(dir) => dir.join(&rel_path),
|
||||
Err(_) => std::path::PathBuf::from(&rel_path),
|
||||
};
|
||||
println!("DEBUG: Attempting to read markdown file at absolute path: {:?}", abs_path);
|
||||
match fs::read_to_string(&abs_path) {
|
||||
Ok(md) => {
|
||||
println!("DEBUG: Successfully read markdown file");
|
||||
let parser = Parser::new_ext(&md, Options::all());
|
||||
let mut html_output = String::new();
|
||||
html::push_html(&mut html_output, parser);
|
||||
context.insert("contract_section_content", &html_output);
|
||||
},
|
||||
Err(e) => {
|
||||
let error_msg = format!("Error: Could not read contract section markdown at '{:?}': {}", abs_path, e);
|
||||
println!("{}", error_msg);
|
||||
context.insert("contract_section_content_error", &error_msg);
|
||||
}
|
||||
}
|
||||
context.insert("toc", &toc);
|
||||
}
|
||||
|
||||
// Count signed signers for the template
|
||||
let signed_signers = contract.signers.iter().filter(|s| s.status == SignerStatus::Signed).count();
|
||||
@@ -327,6 +377,8 @@ impl ContractController {
|
||||
|
||||
// Mock contract 1 - Signed Service Agreement
|
||||
let mut contract1 = Contract {
|
||||
content_dir: None,
|
||||
toc: None,
|
||||
id: "contract-001".to_string(),
|
||||
title: "Digital Hub Service Agreement".to_string(),
|
||||
description: "Service agreement for cloud hosting and digital infrastructure services provided by the Zanzibar Digital Hub.".to_string(),
|
||||
@@ -381,6 +433,8 @@ impl ContractController {
|
||||
|
||||
// Mock contract 2 - Pending Signatures
|
||||
let mut contract2 = Contract {
|
||||
content_dir: None,
|
||||
toc: None,
|
||||
id: "contract-002".to_string(),
|
||||
title: "Software Development Agreement".to_string(),
|
||||
description: "Agreement for custom software development services for the Zanzibar Digital Marketplace platform.".to_string(),
|
||||
@@ -450,7 +504,56 @@ impl ContractController {
|
||||
signers: Vec::new(),
|
||||
revisions: Vec::new(),
|
||||
current_version: 1,
|
||||
content_dir: Some("src/content/contract-003".to_string()),
|
||||
toc: Some(vec![
|
||||
TocItem {
|
||||
title: "Cover".to_string(),
|
||||
file: "cover.md".to_string(),
|
||||
children: vec![],
|
||||
},
|
||||
TocItem {
|
||||
title: "1. Purpose".to_string(),
|
||||
file: "1-purpose.md".to_string(),
|
||||
children: vec![],
|
||||
},
|
||||
TocItem {
|
||||
title: "2. Tokenization Process".to_string(),
|
||||
file: "2-tokenization-process.md".to_string(),
|
||||
children: vec![],
|
||||
},
|
||||
TocItem {
|
||||
title: "3. Revenue Sharing".to_string(),
|
||||
file: "3-revenue-sharing.md".to_string(),
|
||||
children: vec![],
|
||||
},
|
||||
TocItem {
|
||||
title: "4. Governance".to_string(),
|
||||
file: "4-governance.md".to_string(),
|
||||
children: vec![],
|
||||
},
|
||||
TocItem {
|
||||
title: "Appendix A: Properties".to_string(),
|
||||
file: "appendix-a.md".to_string(),
|
||||
children: vec![],
|
||||
},
|
||||
TocItem {
|
||||
title: "Appendix B: Technical Specs".to_string(),
|
||||
file: "appendix-b.md".to_string(),
|
||||
children: vec![],
|
||||
},
|
||||
TocItem {
|
||||
title: "Appendix C: Revenue Formula".to_string(),
|
||||
file: "appendix-c.md".to_string(),
|
||||
children: vec![],
|
||||
},
|
||||
TocItem {
|
||||
title: "Appendix D: Governance Framework".to_string(),
|
||||
file: "appendix-d.md".to_string(),
|
||||
children: vec![],
|
||||
},
|
||||
]),
|
||||
};
|
||||
|
||||
|
||||
// Add potential signers to contract 3 (still in draft)
|
||||
contract3.signers.push(ContractSigner {
|
||||
@@ -471,17 +574,62 @@ impl ContractController {
|
||||
comments: None,
|
||||
});
|
||||
|
||||
// Add revisions to contract 3
|
||||
contract3.revisions.push(ContractRevision {
|
||||
version: 1,
|
||||
content: "<h1>Digital Asset Tokenization Agreement</h1><p>This Digital Asset Tokenization Agreement (the \"Agreement\") is entered into between Zanzibar Property Consortium (\"Tokenizer\") and the property owners listed in Appendix A (\"Owners\").</p><h2>1. Purpose</h2><p>The purpose of this Agreement is to establish the terms and conditions for tokenizing real estate assets on the Zanzibar blockchain network.</p><h2>2. Tokenization Process</h2><p>Tokenizer shall create digital tokens representing ownership interests in the properties listed in Appendix A according to the specifications in Appendix B.</p><h2>3. Revenue Sharing</h2><p>Revenue generated from the tokenized properties shall be distributed according to the formula set forth in Appendix C.</p><h2>4. Governance</h2><p>Decisions regarding the management of tokenized properties shall be made according to the governance framework outlined in Appendix D.</p>".to_string(),
|
||||
created_at: Utc::now() - Duration::days(3),
|
||||
created_by: "Nala Okafor".to_string(),
|
||||
comments: Some("Initial draft of the tokenization agreement.".to_string()),
|
||||
});
|
||||
// Add ToC and content directory to contract 3
|
||||
contract3.content_dir = Some("src/content/contract-003".to_string());
|
||||
contract3.toc = Some(vec![
|
||||
TocItem {
|
||||
title: "Digital Asset Tokenization Agreement".to_string(),
|
||||
file: "cover.md".to_string(),
|
||||
children: vec![
|
||||
TocItem {
|
||||
title: "1. Purpose".to_string(),
|
||||
file: "1-purpose.md".to_string(),
|
||||
children: vec![],
|
||||
},
|
||||
TocItem {
|
||||
title: "2. Tokenization Process".to_string(),
|
||||
file: "2-tokenization-process.md".to_string(),
|
||||
children: vec![],
|
||||
},
|
||||
TocItem {
|
||||
title: "3. Revenue Sharing".to_string(),
|
||||
file: "3-revenue-sharing.md".to_string(),
|
||||
children: vec![],
|
||||
},
|
||||
TocItem {
|
||||
title: "4. Governance".to_string(),
|
||||
file: "4-governance.md".to_string(),
|
||||
children: vec![],
|
||||
},
|
||||
TocItem {
|
||||
title: "Appendix A: Properties".to_string(),
|
||||
file: "appendix-a.md".to_string(),
|
||||
children: vec![],
|
||||
},
|
||||
TocItem {
|
||||
title: "Appendix B: Specifications".to_string(),
|
||||
file: "appendix-b.md".to_string(),
|
||||
children: vec![],
|
||||
},
|
||||
TocItem {
|
||||
title: "Appendix C: Revenue Formula".to_string(),
|
||||
file: "appendix-c.md".to_string(),
|
||||
children: vec![],
|
||||
},
|
||||
TocItem {
|
||||
title: "Appendix D: Governance Framework".to_string(),
|
||||
file: "appendix-d.md".to_string(),
|
||||
children: vec![],
|
||||
},
|
||||
],
|
||||
}
|
||||
]);
|
||||
// No revision content for contract 3, content is in markdown files.
|
||||
|
||||
// Mock contract 4 - Rejected
|
||||
let mut contract4 = Contract {
|
||||
content_dir: None,
|
||||
toc: None,
|
||||
id: "contract-004".to_string(),
|
||||
title: "Data Sharing Agreement".to_string(),
|
||||
description: "Agreement governing the sharing of anonymized data between Zanzibar Digital Hub and research institutions.".to_string(),
|
||||
@@ -528,6 +676,8 @@ impl ContractController {
|
||||
|
||||
// Mock contract 5 - Active
|
||||
let mut contract5 = Contract {
|
||||
content_dir: None,
|
||||
toc: None,
|
||||
id: "contract-005".to_string(),
|
||||
title: "Digital Identity Verification Service Agreement".to_string(),
|
||||
description: "Agreement for providing digital identity verification services to businesses operating in the Zanzibar Autonomous Zone.".to_string(),
|
||||
|
Reference in New Issue
Block a user