logicaffeine_web/ui/pages/
terms.rs1use dioxus::prelude::*;
11use crate::ui::components::main_nav::{MainNav, ActivePage};
12use crate::ui::components::footer::Footer;
13use crate::ui::seo::{JsonLdMultiple, PageHead, organization_schema, webpage_schema, breadcrumb_schema, BreadcrumbItem, pages as seo_pages};
14
15#[cfg(not(target_arch = "wasm32"))]
18const TERMS_HTML: &str = include_str!("../../../terms.html");
19
20const LEGAL_STYLE: &str = r#"
21.legal-container {
22 min-height: 100vh;
23 display: flex;
24 flex-direction: column;
25 background: linear-gradient(135deg, #1a1a2e 0%, #16213e 50%, #0f3460 100%);
26}
27
28.legal-content {
29 flex: 1;
30 max-width: 900px;
31 margin: 0 auto;
32 padding: 40px 20px 60px;
33 width: 100%;
34}
35
36.legal-content-inner {
37 background: rgba(255, 255, 255, 0.98);
38 border-radius: 16px;
39 padding: 40px;
40 box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
41}
42
43.legal-footer {
44 border-top: 1px solid rgba(255,255,255,0.06);
45 padding: 24px 20px;
46 text-align: center;
47 color: rgba(229,231,235,0.56);
48 font-size: 13px;
49}
50
51.legal-footer a {
52 color: rgba(229,231,235,0.72);
53 text-decoration: none;
54 margin: 0 8px;
55}
56
57.legal-footer a:hover {
58 color: #a78bfa;
59}
60
61.github-link {
62 display: inline-flex;
63 align-items: center;
64 gap: 6px;
65}
66"#;
67
68#[component]
69pub fn Terms() -> Element {
70 let breadcrumbs = vec![
71 BreadcrumbItem { name: "Home", path: "/" },
72 BreadcrumbItem { name: "Terms of Service", path: "/terms" },
73 ];
74 let schemas = vec![
75 organization_schema(),
76 webpage_schema("Terms of Service", "Terms and conditions for using LOGICAFFEINE. Business Source License details and usage policies.", "/terms"),
77 breadcrumb_schema(&breadcrumbs),
78 ];
79
80 rsx! {
81 PageHead {
82 title: seo_pages::TERMS.title,
83 description: seo_pages::TERMS.description,
84 canonical_path: seo_pages::TERMS.canonical_path,
85 }
86 style { "{LEGAL_STYLE}" }
87 JsonLdMultiple { schemas }
88
89 div { class: "legal-container",
90 MainNav { active: ActivePage::Other, subtitle: Some("Terms of Use") }
91
92 main { class: "legal-content",
93 TermsBody {}
94 }
95
96 Footer {}
97 }
98 }
99}
100
101#[cfg(not(target_arch = "wasm32"))]
102#[component]
103fn TermsBody() -> Element {
104 rsx! {
105 div { class: "legal-content-inner", dangerous_inner_html: "{TERMS_HTML}" }
106 }
107}
108
109#[cfg(target_arch = "wasm32")]
110#[component]
111fn TermsBody() -> Element {
112 let mut body = use_resource(|| crate::ui::data_fetch::fetch_static_text("/data/terms.html"));
113 let state = body.read_unchecked();
114 match &*state {
115 Some(Ok(html)) => rsx! {
116 div { class: "legal-content-inner", dangerous_inner_html: "{html}" }
117 },
118 Some(Err(e)) => rsx! {
119 div { class: "legal-content-inner",
120 p { "The terms of service failed to load: {e}" }
121 button { onclick: move |_| body.restart(), "Retry" }
122 }
123 },
124 None => rsx! {
125 div { class: "legal-content-inner", p { "Loading\u{2026}" } }
126 },
127 }
128}