Compare commits

..

No commits in common. "ee252aec132b3b4a6e31876207bf45851e30469f" and "1b656dc8340068f241a30bf62f20e34a8eebcc5b" have entirely different histories.

19 changed files with 149 additions and 427 deletions

117
Cargo.lock generated
View file

@ -335,56 +335,6 @@ dependencies = [
"libc", "libc",
] ]
[[package]]
name = "anstream"
version = "0.6.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "301af1932e46185686725e0fad2f8f2aa7da69dd70bf6ecc44d6b703844a3933"
dependencies = [
"anstyle",
"anstyle-parse",
"anstyle-query",
"anstyle-wincon",
"colorchoice",
"is_terminal_polyfill",
"utf8parse",
]
[[package]]
name = "anstyle"
version = "1.0.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "862ed96ca487e809f1c8e5a8447f6ee2cf102f846893800b20cebdf541fc6bbd"
[[package]]
name = "anstyle-parse"
version = "0.2.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2"
dependencies = [
"utf8parse",
]
[[package]]
name = "anstyle-query"
version = "1.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6c8bdeb6047d8983be085bab0ba1472e6dc604e7041dbf6fcd5e71523014fae9"
dependencies = [
"windows-sys 0.59.0",
]
[[package]]
name = "anstyle-wincon"
version = "3.0.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "403f75924867bb1033c59fbf0797484329750cfbe3c4325cd33127941fabc882"
dependencies = [
"anstyle",
"once_cell_polyfill",
"windows-sys 0.59.0",
]
[[package]] [[package]]
name = "anyhow" name = "anyhow"
version = "1.0.98" version = "1.0.98"
@ -689,46 +639,6 @@ dependencies = [
"stacker", "stacker",
] ]
[[package]]
name = "clap"
version = "4.5.40"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "40b6887a1d8685cebccf115538db5c0efe625ccac9696ad45c409d96566e910f"
dependencies = [
"clap_builder",
"clap_derive",
]
[[package]]
name = "clap_builder"
version = "4.5.40"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e0c66c08ce9f0c698cbce5c0279d0bb6ac936d8674174fe48f736533b964f59e"
dependencies = [
"anstream",
"anstyle",
"clap_lex",
"strsim",
]
[[package]]
name = "clap_derive"
version = "4.5.40"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d2c7947ae4cc3d851207c1adb5b5e260ff0cca11446b1d6d1423788e442257ce"
dependencies = [
"heck",
"proc-macro2",
"quote",
"syn 2.0.103",
]
[[package]]
name = "clap_lex"
version = "0.7.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b94f61472cee1439c0b966b47e3aca9ae07e45d070759512cd390ea2bebc6675"
[[package]] [[package]]
name = "color-eyre" name = "color-eyre"
version = "0.6.5" version = "0.6.5"
@ -756,12 +666,6 @@ dependencies = [
"tracing-error", "tracing-error",
] ]
[[package]]
name = "colorchoice"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75"
[[package]] [[package]]
name = "concurrent-queue" name = "concurrent-queue"
version = "2.5.0" version = "2.5.0"
@ -1720,12 +1624,6 @@ dependencies = [
"windows-sys 0.59.0", "windows-sys 0.59.0",
] ]
[[package]]
name = "is_terminal_polyfill"
version = "1.70.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf"
[[package]] [[package]]
name = "itoa" name = "itoa"
version = "1.0.15" version = "1.0.15"
@ -2132,12 +2030,6 @@ version = "1.21.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
[[package]]
name = "once_cell_polyfill"
version = "1.70.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a4895175b425cb1f87721b59f0f286c2092bd4af812243672510e1ac53e2e0ad"
[[package]] [[package]]
name = "openssl" name = "openssl"
version = "0.10.73" version = "0.10.73"
@ -3202,7 +3094,7 @@ dependencies = [
] ]
[[package]] [[package]]
name = "tfcsite" name = "tfcapi"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"actix-cors", "actix-cors",
@ -3211,7 +3103,6 @@ dependencies = [
"actix-rt", "actix-rt",
"actix-web", "actix-web",
"async-std", "async-std",
"clap",
"color-eyre", "color-eyre",
"env_logger", "env_logger",
"futures", "futures",
@ -3588,12 +3479,6 @@ version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be"
[[package]]
name = "utf8parse"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
[[package]] [[package]]
name = "uuid" name = "uuid"
version = "1.17.0" version = "1.17.0"

View file

@ -1,5 +1,5 @@
[package] [package]
name = "tfcsite" name = "tfcapi"
version = "0.1.0" version = "0.1.0"
edition = "2021" edition = "2021"
@ -32,7 +32,6 @@ tracing-actix-web = "0.7.14"
color-eyre = "0.6.3" color-eyre = "0.6.3"
pretty_assertions = "1.4.1" pretty_assertions = "1.4.1"
sqlx = { version = "0.8.2", features = ["sqlite"] } sqlx = { version = "0.8.2", features = ["sqlite"] }
clap = { version = "4.5.40", features = ["derive"] }
[profile.dev] [profile.dev]
opt-level = 0 opt-level = 0

View file

@ -1,7 +1,5 @@
# The base URL of the site; the only required configuration variable. # The base URL of the site; the only required configuration variable.
# base_url = "https://tfcconnection.org" base_url = "https://tfcconnection.org"
# used when developing
base_url = "/"
# The site title and description; used in feeds by default. # The site title and description; used in feeds by default.
title = "TFC Connection" title = "TFC Connection"
@ -125,7 +123,7 @@ include_content = true
# become too big to load on the site. Defaults to not being set. # become too big to load on the site. Defaults to not being set.
truncate_content_length = 100 truncate_content_length = 100
index_format = "elasticlunr_javascript" index_format = "elasticlunr_json"
# Optional translation object for the default language # Optional translation object for the default language
# Example: # Example:
@ -162,7 +160,6 @@ taxonomies = [
# #
[extra] [extra]
enable_search = true enable_search = true
enable_sidebar = false
[extra.navbar] [extra.navbar]

View file

@ -22,10 +22,10 @@ Fill out now!
</span> </span>
</div> </div>
{{ spacing(height="h-8") }} {{ spacing(height="h-4") }}
> If you need to fill out a camp health form, please do so [here](/camp-health-form). > If you need to fill out a camp health form, please do so [here](/camp-health-form).
{{ spacing(height="h-4") }}
> If you need to pay for your camp form, pay for registration ($100) [here](https://secure.myvanco.com/L-Z772/campaign/C-13JPJ) or pay for the full price ($200) [here](https://secure.myvanco.com/L-Z772/campaign/C-13JQE). > If you need to pay for your camp form, pay for registration ($100) [here](https://secure.myvanco.com/L-Z772/campaign/C-13JPJ) or pay for the full price ($200) [here](https://secure.myvanco.com/L-Z772/campaign/C-13JQE).
{{ spacing(height="h-8") }} {{ spacing(height="h-8") }}

View file

@ -66,13 +66,15 @@
# cp -r ${blowfish} themes/blowfish # cp -r ${blowfish} themes/blowfish
# ls themes/blowfish # ls themes/blowfish
# ''; # '';
buildPhase = '' # buildPhase = ''
${pkgs.tailwindcss_4}/bin/tailwindcss -i static/css/base.css -o static/css/main.css # NODE_ENV=production ./themes/blowfish/node_modules/tailwindcss/lib/cli.js -c ./themes/blowfish/tailwind.config.js -i ./themes/blowfish/assets/css/main.css -o ./assets/css/compiled/main.css --jit && hugo --gc --minify
${pkgs.zola}/bin/zola build # ${pkgs.hugo}/bin/hugo --minify
''; # '';
installPhase = '' # installPhase = ''
cp -r public $out/ # ls -l
''; # cp -r public $out/
# ls -l $out
# '';
buildInputs = bi; buildInputs = bi;
nativeBuildInputs = nbi; nativeBuildInputs = nbi;
}; };

View file

@ -3,7 +3,7 @@ default:
build: build:
tailwindcss -i static/css/base.css -o static/css/main.css && zola build tailwindcss -i static/css/base.css -o static/css/main.css && zola build
serve: serve:
zola serve -p 4242 zola serve
uglify: uglify:
uglifyjs ./src/js/main.js --compress --mangle -o ./static/js/main.js && uglifyjs ./src/js/page.js --compress --mangle -o ./static/js/page.js && uglifyjs ./src/js/search.js --compress --mangle -o ./static/js/search.js && uglifyjs ./src/js/lang.js --compress --mangle -o ./static/js/lang.js uglifyjs ./src/js/main.js --compress --mangle -o ./static/js/main.js && uglifyjs ./src/js/page.js --compress --mangle -o ./static/js/page.js && uglifyjs ./src/js/search.js --compress --mangle -o ./static/js/search.js && uglifyjs ./src/js/lang.js --compress --mangle -o ./static/js/lang.js
dev: dev:
@ -14,5 +14,3 @@ clean:
cargo clean cargo clean
test: test:
RUST_LOG=debug cargo test --benches --tests --all-features -- --nocapture RUST_LOG=debug cargo test --benches --tests --all-features -- --nocapture
run:
tailwindcss -i static/css/base.css -o static/css/main.css --watch & zola build && cargo run -- -d

View file

@ -6,8 +6,8 @@ use color_eyre::eyre::{Context, Result};
use futures::FutureExt; use futures::FutureExt;
use lettre::{message::SinglePart, Message}; use lettre::{message::SinglePart, Message};
use maud::{html, Markup, DOCTYPE}; use maud::{html, Markup, DOCTYPE};
use reqwest::{Client, Response}; use reqwest::Client;
use tracing::{debug, error, info}; use tracing::{error, info};
#[derive(Debug, MultipartForm)] #[derive(Debug, MultipartForm)]
struct CampForm { struct CampForm {
@ -39,30 +39,27 @@ struct CampForm {
health_form: Text<String>, health_form: Text<String>,
} }
impl From<&CampForm> for HashMap<&str, String> { impl From<&CampForm> for HashMap<i32, String> {
fn from(form: &CampForm) -> Self { fn from(form: &CampForm) -> Self {
let mut map = HashMap::new(); let mut map = HashMap::new();
map.insert(63, format!("{} {}", form.first_name.0, form.last_name.0));
map.insert( map.insert(
"Full_Name", 64,
format!("{} {}", form.first_name.0, form.last_name.0),
);
map.insert(
"Parent_Name",
format!("{} {}", form.parent_first_name.0, form.parent_last_name.0), format!("{} {}", form.parent_first_name.0, form.parent_last_name.0),
); );
map.insert("Parent_Phone", form.parent_phone.0.clone()); map.insert(65, form.parent_phone.0.clone());
map.insert("Parent_Email", form.parent_email.0.clone().clone()); map.insert(66, form.parent_email.0.clone().clone());
map.insert("Birth_Date", form.birthdate.0.clone()); map.insert(67, form.birthdate.0.clone());
map.insert("Gender", form.gender.0.clone()); map.insert(69, form.gender.0.clone());
map.insert("Street_Address", form.street.0.clone()); map.insert(70, form.street.0.clone());
map.insert("City", form.city.0.clone()); map.insert(71, form.city.0.clone());
map.insert("State", form.state.0.clone()); map.insert(72, form.state.0.clone());
map.insert("Zipcode", form.zip.0.clone().to_string()); map.insert(73, form.zip.0.clone().to_string());
map.insert("Grade", form.grade.0.clone()); map.insert(74, form.grade.0.clone());
map.insert("Week_Chosen", form.week.0.clone()); map.insert(75, form.week.0.clone());
map.insert("Shirt_Size", form.shirt.0.clone()); map.insert(76, form.shirt.0.clone());
map.insert("Registration", form.registration.0.clone()); map.insert(77, form.registration.0.clone());
map.insert("Health_Form", form.health_form.0.clone()); map.insert(115, form.health_form.0.clone());
map map
} }
} }
@ -295,21 +292,19 @@ pub async fn camp_form(MultipartForm(form): MultipartForm<CampForm>) -> HttpResp
} }
} }
async fn store_camp_form(map: HashMap<&str, String>) -> Result<Response> { async fn store_camp_form(map: HashMap<i32, String>) -> Result<()> {
let request = Client::new(); let request = Client::new();
let mut json = HashMap::new(); let mut json = HashMap::new();
let mut fields = HashMap::new(); json.insert("data", map);
fields.insert("fields", map); request
json.insert("records", vec![fields]); .post("https://staff.tfcconnection.org/apps/tables/api/1/tables/5/rows")
let response = request .basic_auth("chris", Some("2VHeGxeC^Zf9KqFK^G@Pt!zu2q^6@b"))
.post("https://table.tfcconnection.org/api/docs/e8SFoTHpmJuFQsiMhRTXCi/tables/Camp_Data/records") .header("OCS-APIRequest", "true")
.bearer_auth("b8189d1b315548aa610db2fd3a43177a967cd41f")
.header("Content-Type", "application/json") .header("Content-Type", "application/json")
.json(&json) .json(&json)
.send() .send()
.await?; .await?;
debug!(?response); Ok(())
Ok(response)
} }
#[cfg(test)] #[cfg(test)]
@ -334,7 +329,7 @@ mod test {
grade: Text(String::from("junior")), grade: Text(String::from("junior")),
shirt: Text(String::from("medium")), shirt: Text(String::from("medium")),
allergies: Text(String::from("Cool beans")), allergies: Text(String::from("Cool beans")),
week: Text(String::from("week1")), week: Text(String::from("1")),
registration: Text(String::from("later")), registration: Text(String::from("later")),
health_form: Text(String::from("I guess")), health_form: Text(String::from("I guess")),
} }
@ -347,7 +342,7 @@ mod test {
let map = HashMap::from(&form); let map = HashMap::from(&form);
let res = store_camp_form(map).await; let res = store_camp_form(map).await;
match res { match res {
Ok(r) => assert!(r.status().is_success(), "Failed to store: {:?}", r), Ok(_) => assert!(true),
Err(e) => assert!(false, "Failed storing test: {e}"), Err(e) => assert!(false, "Failed storing test: {e}"),
} }
} }

View file

@ -12,7 +12,7 @@ use lettre::{
Message, Message,
}; };
use maud::{html, Markup, DOCTYPE}; use maud::{html, Markup, DOCTYPE};
use reqwest::{Client, Response}; use reqwest::Client;
use tracing::{error, info}; use tracing::{error, info};
use crate::email::send_email; use crate::email::send_email;
@ -75,46 +75,40 @@ struct HealthForm {
registration: Text<String>, registration: Text<String>,
} }
impl From<&HealthForm> for HashMap<&str, String> { impl From<&HealthForm> for HashMap<i32, String> {
fn from(form: &HealthForm) -> Self { fn from(form: &HealthForm) -> Self {
let mut map = HashMap::new(); let mut map = HashMap::new();
map.insert(37, format!("{} {}", form.first_name.0, form.last_name.0));
map.insert( map.insert(
"Student_Name", 38,
format!("{} {}", form.first_name.0, form.last_name.0),
);
map.insert(
"Parent_Name",
format!("{} {}", form.parent_first_name.0, form.parent_last_name.0), format!("{} {}", form.parent_first_name.0, form.parent_last_name.0),
); );
map.insert("Birthdate", form.birthdate.0.clone()); map.insert(39, form.birthdate.0.clone());
map.insert("Street", form.street.0.clone()); map.insert(40, form.street.0.clone());
map.insert("City", form.city.0.clone()); map.insert(41, form.city.0.clone());
map.insert("State", form.state.0.clone()); map.insert(42, form.state.0.clone());
map.insert("Zipcode", form.zip.0.clone()); map.insert(43, form.zip.0.clone());
map.insert("Parent_Phone", form.parent_cellphone.0.clone()); map.insert(44, form.parent_cellphone.0.clone());
map.insert("Homephone", form.homephone.0.clone()); map.insert(45, form.homephone.0.clone());
map.insert(46, format!("{} {}", form.contact.0, form.contact_phone.0));
map.insert(47, form.doctorname.0.clone());
map.insert(48, form.doctorcity.0.clone());
map.insert(49, form.doctorphone.0.clone());
map.insert(50, form.medical.0.clone());
map.insert(51, form.insurance.0.clone());
map.insert(52, form.policy_number.0.clone());
map.insert(54, form.agreement.0.clone());
map.insert( map.insert(
"Emergency_Contact", 55,
format!("{} {}", form.contact.0, form.contact_phone.0),
);
map.insert("Doctor", form.doctorname.0.clone());
map.insert("Doctor_City", form.doctorcity.0.clone());
map.insert("Doctor_Phone", form.doctorphone.0.clone());
map.insert("Medical_Coverage", form.medical.0.clone());
map.insert("Insurance_Name", form.insurance.0.clone());
map.insert("Policy_Number", form.policy_number.0.clone());
map.insert("Agreement", form.agreement.0.clone());
map.insert(
"Allergies",
format!("{} \n {}", form.allergies.0, form.allergies_other.0), format!("{} \n {}", form.allergies.0, form.allergies_other.0),
); );
map.insert("Specific_Allergies", form.specific_allergies.0.clone()); map.insert(56, form.specific_allergies.0.clone());
map.insert("Allergic_Treatments", form.treatment.0.clone()); map.insert(57, form.treatment.0.clone());
map.insert("Conditions", form.conditions.0.clone()); map.insert(58, form.conditions.0.clone());
map.insert("Tetanus_Shot_Date", form.tetanus.0.clone()); map.insert(59, form.tetanus.0.clone());
map.insert("Medication_Schedule", form.medication.0.clone()); map.insert(60, form.medication.0.clone());
map.insert("Other_Notes", form.notes.0.clone()); map.insert(61, form.notes.0.clone());
map.insert("Swimming_Ability", form.swimming.0.clone()); map.insert(62, form.swimming.0.clone());
map map
} }
} }
@ -437,22 +431,22 @@ pub async fn health_form(MultipartForm(mut form): MultipartForm<HealthForm>) ->
// HttpResponse::Ok().body("hi") // HttpResponse::Ok().body("hi")
} }
async fn store_form(map: HashMap<&str, String>) -> Result<Response> { async fn store_form(map: HashMap<i32, String>) -> Result<()> {
let client = Client::new(); let client = Client::new();
let mut json = HashMap::new(); let mut json = HashMap::new();
let mut fields = HashMap::new(); json.insert("data", map);
fields.insert("fields", map);
json.insert("records", vec![fields]);
let res = client let res = client
.post("https://table.tfcconnection.org/api/docs/e8SFoTHpmJuFQsiMhRTXCi/tables/Health_Data/records") .post("https://staff.tfcconnection.org/ocs/v2.php/apps/tables/api/2/tables/4/rows")
.bearer_auth("b8189d1b315548aa610db2fd3a43177a967cd41f") .basic_auth("chris", Some("2VHeGxeC^Zf9KqFK^G@Pt!zu2q^6@b"))
.header("OCS-APIRequest", "true")
.header("Content-Type", "application/json") .header("Content-Type", "application/json")
.json(&json) .json(&json)
.send() .send()
.await?; .await?;
if res.status().is_success() { if res.status().is_success() {
Ok(res) let res = res.text().await.unwrap();
Ok(())
} else { } else {
Err(eyre!( Err(eyre!(
"Problem in storing data: {:?}", "Problem in storing data: {:?}",
@ -460,69 +454,3 @@ async fn store_form(map: HashMap<&str, String>) -> Result<Response> {
)) ))
} }
} }
#[cfg(test)]
mod test {
use super::*;
use actix_web::test;
fn form() -> HealthForm {
HealthForm {
first_name: Text("Frodo".into()),
last_name: Text("Braggins".into()),
parent_first_name: Text("Bilbo".into()),
parent_last_name: Text("Braggins".into()),
birthdate: Text(String::from("1845-09-12")),
street: Text(String::from("1234 Bag End")),
city: Text(String::from("The Shire")),
state: Text(String::from("Hobbiton")),
zip: Text(String::from("88888")),
allergies: Text(String::from("Cool beans")),
registration: Text(String::from("later")),
parent_cellphone: Text(String::from("later")),
homephone: Text("test".into()),
contact: Text("test".into()),
contact_phone: Text("test".into()),
doctorname: Text("test".into()),
doctorcity: Text("test".into()),
doctorphone: Text("test".into()),
medical: Text("test".into()),
insurance: Text("test".into()),
policy_number: Text("test".into()),
allergies_other: Text("test".into()),
specific_allergies: Text("test".into()),
treatment: Text("test".into()),
conditions: Text("test".into()),
tetanus: Text("test".into()),
swimming: Text("test".into()),
medication: Text("test".into()),
notes: Text("test".into()),
agreement: Text("test".into()),
file: None,
}
}
#[test]
async fn test_nc_post() {
let form = form();
assert!(!form.first_name.is_empty());
let map = HashMap::from(&form);
let res = store_form(map).await;
match res {
Ok(r) => assert!(r.status().is_success(), "Failed to store: {:?}", r),
Err(e) => assert!(false, "Failed storing test: {e}"),
}
}
#[test]
async fn test_email() {
let mut form = form();
assert!(!form.first_name.is_empty());
match form.send_email() {
Ok(m) => {
assert!(crate::email::send_email(m).await.is_ok())
}
Err(e) => assert!(false, "Failed emailing test: {e}"),
}
}
}

View file

@ -7,7 +7,7 @@ use actix_web::body::MessageBody;
use actix_web::dev::{ServiceRequest, ServiceResponse}; use actix_web::dev::{ServiceRequest, ServiceResponse};
use actix_web::{web, App, Error, HttpServer}; use actix_web::{web, App, Error, HttpServer};
use api::camp_form::camp_form; use api::camp_form::camp_form;
use api::contact::contact_form; use api::contact::{self, contact_form};
use api::health_form::health_form; use api::health_form::health_form;
use api::local_trip_form::local_form; use api::local_trip_form::local_form;
use api::mt_form::mt_form; use api::mt_form::mt_form;
@ -15,7 +15,6 @@ use api::{
mt_church_form::mt_church_form, mt_parent_form::mt_parent_form, mt_church_form::mt_church_form, mt_parent_form::mt_parent_form,
mt_teacher_form::mt_teacher_form, mt_teacher_form::mt_teacher_form,
}; };
use clap::Parser;
use color_eyre::eyre::Context; use color_eyre::eyre::Context;
use color_eyre::Result; use color_eyre::Result;
use sqlx::{Connection, SqliteConnection}; use sqlx::{Connection, SqliteConnection};
@ -46,65 +45,46 @@ impl RootSpanBuilder for DomainRootSpanBuilder {
fn on_request_end<B: MessageBody>(_span: Span, _outcome: &Result<ServiceResponse<B>, Error>) {} fn on_request_end<B: MessageBody>(_span: Span, _outcome: &Result<ServiceResponse<B>, Error>) {}
} }
#[derive(Debug, Parser)]
#[command(name = "tfcsite", version, about)]
struct Cli {
#[arg(short, long)]
dev: bool,
}
#[actix_web::main] #[actix_web::main]
async fn main() -> std::io::Result<()> { async fn main() -> std::io::Result<()> {
let site;
let temp;
let logs;
if Cli::parse().dev {
site = "./public";
logs = "/tmp/tfcsite";
temp = "/tmp/tfcsite";
} else {
site = "../public";
logs = "/storage/logs/tfcsite";
temp = "/tmp/tfcsite";
}
std::fs::create_dir_all(&logs)?;
std::fs::create_dir_all(&temp)?;
let timer = let timer =
tracing_subscriber::fmt::time::ChronoLocal::new("%Y-%m-%d_%I:%M:%S%.6f %P".to_owned()); tracing_subscriber::fmt::time::ChronoLocal::new("%Y-%m-%d_%I:%M:%S%.6f %P".to_owned());
let logfile = RollingFileAppender::builder() let logfile = RollingFileAppender::builder()
.rotation(Rotation::DAILY) .rotation(Rotation::DAILY)
.filename_prefix("api") .filename_prefix("api")
.filename_suffix("log") .filename_suffix("log")
.build(&logs) .build(if DEV_MODE {
"/tmp/tfcsite"
} else {
"/storage/logs/tfcsite"
})
.expect("Shouldn't"); .expect("Shouldn't");
let file_filter = EnvFilter::builder() let filter = EnvFilter::builder()
.with_default_directive(LevelFilter::WARN.into()) .with_default_directive(LevelFilter::WARN.into())
.parse_lossy("tfcsite=debug"); .parse_lossy("tfcapi=debug");
let logfile_layer = tracing_subscriber::fmt::layer() let logfile_layer = tracing_subscriber::fmt::layer()
.with_writer(logfile) .with_writer(logfile)
.with_line_number(true) .with_line_number(true)
.with_level(true) .with_level(true)
.with_target(true) .with_target(true)
.with_ansi(false) .with_ansi(false)
.with_timer(timer.clone()) .with_timer(timer.clone());
.with_filter(file_filter);
let stdout_filter = EnvFilter::builder()
.with_default_directive(LevelFilter::WARN.into())
.parse_lossy("tfcsite=debug");
let stdout_layer = tracing_subscriber::fmt::layer() let stdout_layer = tracing_subscriber::fmt::layer()
.pretty() .pretty()
.with_line_number(true) .with_line_number(true)
.with_target(true) .with_target(true)
.with_timer(timer) .with_timer(timer)
.with_filter(stdout_filter); .with_filter(filter);
let filter = EnvFilter::builder()
let subscriber = tracing_subscriber::registry().with(logfile_layer.and_then(stdout_layer)); .with_default_directive(LevelFilter::WARN.into())
.parse_lossy("tfcapi=debug");
let subscriber = tracing_subscriber::registry()
.with(logfile_layer.with_filter(filter).and_then(stdout_layer));
let _ = tracing::subscriber::set_global_default(subscriber).wrap_err("Tracing broked"); let _ = tracing::subscriber::set_global_default(subscriber).wrap_err("Tracing broked");
std::fs::create_dir_all("/tmp/tfcsite")?;
info!("starting HTTP server at http://localhost:4242"); info!("starting HTTP server at http://localhost:4242");
let conn = SqliteConnection::connect("sqlite://./data.db") let conn = SqliteConnection::connect("sqlite://./data.db")
@ -116,7 +96,11 @@ async fn main() -> std::io::Result<()> {
App::new() App::new()
.app_data(data.clone()) .app_data(data.clone())
.wrap(TracingLogger::<DomainRootSpanBuilder>::new()) .wrap(TracingLogger::<DomainRootSpanBuilder>::new())
.app_data(TempFileConfig::default().directory(&temp)) .app_data(TempFileConfig::default().directory(if DEV_MODE {
"/tmp/tfcsite"
} else {
"/storage/logs/tfcsite"
}))
.service(mt_form) .service(mt_form)
.service(health_form) .service(health_form)
.service(mt_parent_form) .service(mt_parent_form)
@ -125,7 +109,7 @@ async fn main() -> std::io::Result<()> {
.service(local_form) .service(local_form)
.service(camp_form) .service(camp_form)
.service(contact_form) .service(contact_form)
.service(Files::new("/", &site).index_file("index.html")) .service(Files::new("/", "./public").index_file("index.html"))
}) })
.bind(("localhost", 4242))? .bind(("localhost", 4242))?
.workers(4) .workers(4)

View file

@ -27,17 +27,6 @@
li::marker { li::marker {
color: var(--color-gray-600); color: var(--color-gray-600);
} }
blockquote {
list-style-type: disc;
border-left-width: .25rem;
border-left-color: var(--color-blue-600);
font-style: italic;
font-weight: 500;
padding-left: 1em;
margin-top: 1.6em;
margin-bottom: 1.6em;
}
img { img {
@apply py-0; @apply py-0;

View file

@ -7,7 +7,6 @@
'Noto Color Emoji'; 'Noto Color Emoji';
--font-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New', --font-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New',
monospace; monospace;
--color-blue-200: oklch(88.2% 0.059 254.128);
--color-blue-400: oklch(70.7% 0.165 254.624); --color-blue-400: oklch(70.7% 0.165 254.624);
--color-blue-500: oklch(62.3% 0.214 259.815); --color-blue-500: oklch(62.3% 0.214 259.815);
--color-blue-600: oklch(54.6% 0.245 262.881); --color-blue-600: oklch(54.6% 0.245 262.881);
@ -352,6 +351,9 @@
.mt-16 { .mt-16 {
margin-top: calc(var(--spacing) * 16); margin-top: calc(var(--spacing) * 16);
} }
.mt-20 {
margin-top: calc(var(--spacing) * 20);
}
.mt-40 { .mt-40 {
margin-top: calc(var(--spacing) * 40); margin-top: calc(var(--spacing) * 40);
} }
@ -388,9 +390,6 @@
.ml-4 { .ml-4 {
margin-left: calc(var(--spacing) * 4); margin-left: calc(var(--spacing) * 4);
} }
.ml-\[-0\.2em\] {
margin-left: -0.2em;
}
.ml-auto { .ml-auto {
margin-left: auto; margin-left: auto;
} }
@ -458,6 +457,9 @@
.h-24 { .h-24 {
height: calc(var(--spacing) * 24); height: calc(var(--spacing) * 24);
} }
.h-36 {
height: calc(var(--spacing) * 36);
}
.h-40 { .h-40 {
height: calc(var(--spacing) * 40); height: calc(var(--spacing) * 40);
} }
@ -765,6 +767,9 @@
.bg-indigo-500 { .bg-indigo-500 {
background-color: var(--color-indigo-500); background-color: var(--color-indigo-500);
} }
.bg-transparent {
background-color: transparent;
}
.bg-white { .bg-white {
background-color: var(--color-white); background-color: var(--color-white);
} }
@ -942,6 +947,9 @@
.text-gray-900 { .text-gray-900 {
color: var(--color-gray-900); color: var(--color-gray-900);
} }
.text-indigo-500 {
color: var(--color-indigo-500);
}
.text-white { .text-white {
color: var(--color-white); color: var(--color-white);
} }
@ -1012,6 +1020,9 @@
--tw-blur: blur(8px); --tw-blur: blur(8px);
filter: var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,); filter: var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,);
} }
.filter {
filter: var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,);
}
.transition { .transition {
transition-property: color, background-color, border-color, outline-color, text-decoration-color, fill, stroke, --tw-gradient-from, --tw-gradient-via, --tw-gradient-to, opacity, box-shadow, transform, translate, scale, rotate, filter, -webkit-backdrop-filter, backdrop-filter; transition-property: color, background-color, border-color, outline-color, text-decoration-color, fill, stroke, --tw-gradient-from, --tw-gradient-via, --tw-gradient-to, opacity, box-shadow, transform, translate, scale, rotate, filter, -webkit-backdrop-filter, backdrop-filter;
transition-timing-function: var(--tw-ease, var(--default-transition-timing-function)); transition-timing-function: var(--tw-ease, var(--default-transition-timing-function));
@ -1187,6 +1198,13 @@
} }
} }
} }
.hover\:bg-gray-100 {
&:hover {
@media (hover: hover) {
background-color: var(--color-gray-100);
}
}
}
.hover\:bg-gray-200 { .hover\:bg-gray-200 {
&:hover { &:hover {
@media (hover: hover) { @media (hover: hover) {
@ -1222,14 +1240,6 @@
} }
} }
} }
.hover\:text-3xl {
&:hover {
@media (hover: hover) {
font-size: var(--text-3xl);
line-height: var(--tw-leading, var(--text-3xl--line-height));
}
}
}
.hover\:text-blue-500 { .hover\:text-blue-500 {
&:hover { &:hover {
@media (hover: hover) { @media (hover: hover) {
@ -1251,6 +1261,13 @@
} }
} }
} }
.hover\:text-indigo-400 {
&:hover {
@media (hover: hover) {
color: var(--color-indigo-400);
}
}
}
.hover\:text-white { .hover\:text-white {
&:hover { &:hover {
@media (hover: hover) { @media (hover: hover) {
@ -1611,11 +1628,6 @@
background-color: var(--color-gray-900); background-color: var(--color-gray-900);
} }
} }
.dark\:text-blue-200 {
@media (prefers-color-scheme: dark) {
color: var(--color-blue-200);
}
}
.dark\:text-gray-200 { .dark\:text-gray-200 {
@media (prefers-color-scheme: dark) { @media (prefers-color-scheme: dark) {
color: var(--color-gray-200); color: var(--color-gray-200);
@ -1704,16 +1716,6 @@
li::marker { li::marker {
color: var(--color-gray-600); color: var(--color-gray-600);
} }
blockquote {
list-style-type: disc;
border-left-width: .25rem;
border-left-color: var(--color-blue-600);
font-style: italic;
font-weight: 500;
padding-left: 1em;
margin-top: 1.6em;
margin-bottom: 1.6em;
}
img { img {
padding-block: calc(var(--spacing) * 0); padding-block: calc(var(--spacing) * 0);
border-radius: var(--radius-lg); border-radius: var(--radius-lg);

File diff suppressed because one or more lines are too long

View file

@ -1,55 +1,6 @@
function toggleSearchModal() { function toggleSearchModal(){var e=document.getElementById("search-modal");e.classList.toggle("opacity-0"),e.classList.toggle("pointer-events-none"),document.body.classList.toggle("search-active"),[...document.body.classList].includes("search-active")&&(document.getElementById("search-input").value="",document.getElementById("search-input").focus())}function formatResultItem(e){return console.log(e),htmlToElement(`<li class="flex hover:bg-gray-200 dark:hover:bg-gray-600 text-black dark:text-gray-200 p-2 rounded-lg border border-black dark:border-gray-200 bg-gray-200 dark:bg-gray-500 rounded-lg hover:shadow-xl mb-2">
var e = document.getElementById("search-modal");
e.classList.toggle("opacity-0"), e.classList.toggle("pointer-events-none"), document.body.classList.toggle("search-active"), [...document.body.classList].includes("search-active") && (document.getElementById("search-input").value = "", document.getElementById("search-input").focus())
}
function formatResultItem(e) {
return console.log(e), htmlToElement(`<li class="flex basis-full hover:bg-gray-200 dark:hover:bg-gray-600 text-black dark:text-blue-200 p-2 rounded-lg border border-black dark:border-gray-200 bg-gray-200 dark:bg-gray-700 rounded-lg hover:shadow-xl mb-2 ml-[-0.2em]">
<a href="${e.doc.path}"> <a href="${e.doc.path}">
<span class="dark:text-white text-xl text-bold">${e.doc.title}</span> <span class="text-xl text-bold">${e.doc.title}</span>
<br/> <span class="text-lg">${e.doc.description}</span>
<span class="dark:text-blue-200 text-lg">${e.doc.description}</span>
</a> </a>
</li>`) </li>`)}function htmlToElement(e){var t=document.createElement("template");return e=e.trim(),t.innerHTML=e,t.content.firstChild}document.addEventListener("DOMContentLoaded",function(){document.getElementById("search").addEventListener("click",function(e){e.preventDefault(),toggleSearchModal()});document.querySelector(".modal-overlay").addEventListener("click",toggleSearchModal);for(var e=document.querySelectorAll(".modal-close"),o=0;o<e.length;o++)e[o].addEventListener("click",toggleSearchModal);document.onkeydown=function(e){let t=!1,n=!1;"key"in(e=e||window.event)?(t="Escape"===e.key||"Esc"===e.key,n="k"===e.key&&!0===e.metaKey):(n=75===e.keyCode&&e.metaKey,t=27===e.keyCode),n&&e.preventDefault(),(t&&document.body.classList.contains("search-active")||n)&&toggleSearchModal()};let a=elasticlunr.Index.load(window.searchIndex),l={bool:"AND",fields:{title:{boost:2},body:{boost:1}}},r,c,d=document.getElementById("search-input");document.getElementById("search-results");d.addEventListener("keyup",function(e){if([...document.body.classList].includes("search-active")&&3<d.value.trim().length&&(r=d.value.trim(),c=a.search(r,l),Array.isArray(c))&&0<c.length){var t=document.getElementById("results-list");t.replaceChildren();for(o=0;o<c.length;o++){var n=formatResultItem(c[o]);t.appendChild(n)}}})});
}
function htmlToElement(e) {
var t = document.createElement("template");
return e = e.trim(), t.innerHTML = e, t.content.firstChild
}
document.addEventListener("DOMContentLoaded", function() {
document.getElementById("search").addEventListener("click", function(e) {
e.preventDefault(), toggleSearchModal()
});
document.querySelector(".modal-overlay").addEventListener("click", toggleSearchModal);
for (var e = document.querySelectorAll(".modal-close"), o = 0; o < e.length; o++) e[o].addEventListener("click", toggleSearchModal);
document.onkeydown = function(e) {
let t = !1,
n = !1;
"key" in (e = e || window.event) ? (t = "Escape" === e.key || "Esc" === e.key, n = "k" === e.key && !0 === e.metaKey) : (n = 75 === e.keyCode && e.metaKey, t = 27 === e.keyCode), n && e.preventDefault(), (t && document.body.classList.contains("search-active") || n) && toggleSearchModal()
};
let a = elasticlunr.Index.load(window.searchIndex),
l = {
bool: "AND",
fields: {
title: {
boost: 2
},
body: {
boost: 1
}
}
},
r, c, d = document.getElementById("search-input");
document.getElementById("search-results");
d.addEventListener("keyup", function(e) {
if ([...document.body.classList].includes("search-active") && 3 < d.value.trim().length && (r = d.value.trim(), c = a.search(r, l), Array.isArray(c)) && 0 < c.length) {
var t = document.getElementById("results-list");
t.replaceChildren();
for (o = 0; o < c.length; o++) {
var n = formatResultItem(c[o]);
t.appendChild(n)
}
}
})
});

View file

@ -36,7 +36,7 @@
{% endblock title %} {% endblock title %}
</title> </title>
</head> </head>
<body class="dark:bg-gray-800 flex flex-col h-screen justify-between"> <body class="dark:bg-gray-700 flex flex-col h-screen justify-between">
<!----------------------------------------------------------> <!---------------------------------------------------------->
<!------------------------- NAVBAR -------------------------> <!------------------------- NAVBAR ------------------------->
<!----------------------------------------------------------> <!---------------------------------------------------------->
@ -113,7 +113,7 @@
<div id="search-modal" class="modal opacity-0 pointer-events-none fixed w-full h-full top-0 left-0 flex z-10"> <div id="search-modal" class="modal opacity-0 pointer-events-none fixed w-full h-full top-0 left-0 flex z-10">
<div class="modal-overlay absolute w-full h-full bg-gray-900 opacity-50"></div> <div class="modal-overlay absolute w-full h-full bg-gray-900 opacity-50"></div>
<div class="modal-container text-gray-800 bg-gray-200 dark:bg-gray-800 dark:text-gray-400 w-11/12 md:max-w-md mx-auto rounded-lg shadow-lg z-50 mt-40 sm:mt-32 h-48 border border-2 border-gray-800 dark:border-gray-400"> <div class="modal-container text-gray-800 bg-gray-200 dark:bg-gray-800 dark:text-gray-400 w-11/12 md:max-w-md mx-auto rounded-lg shadow-lg z-50 mt-40 sm:mt-32 h-36 border border-2 border-gray-800 dark:border-gray-400">
<div class="modal-close absolute top-0 right-0 cursor-pointer flex flex-col items-center mt-4 mr-4 text-white text-sm z-50"> <div class="modal-close absolute top-0 right-0 cursor-pointer flex flex-col items-center mt-4 mr-4 text-white text-sm z-50">
<svg class="fill-current text-white" xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 18 18"> <svg class="fill-current text-white" xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 18 18">
@ -141,7 +141,8 @@
<ul id="results-list" class="flex flex-col justify-center max-h-2xl mt-2 overflow-scroll"></ul> <ul id="results-list" class="flex flex-col justify-center max-h-2xl mt-2 overflow-scroll"></ul>
<!--Footer--> <!--Footer-->
<div class="flex justify-end pt-2"> <div class="flex justify-end pt-2">
<button class="px-4 bg-indigo-500 p-3 rounded-lg text-white hover:bg-indigo-400">Search</button> <button class="px-4 bg-transparent p-3 rounded-lg text-indigo-500 hover:bg-gray-100 hover:text-indigo-400 mr-2">Action</button>
<button class="modal-close px-4 bg-indigo-500 p-3 rounded-lg text-white hover:bg-indigo-400">Close</button>
</div> </div>
</div> </div>
@ -229,12 +230,12 @@
<!----------------------------- Mobile menu -----------------------------> <!----------------------------- Mobile menu ----------------------------->
<div id="mobile-menu" class="sm:hidden fixed z-10 overflow-hidden"> <div id="mobile-menu" class="sm:hidden fixed z-10 overflow-hidden">
<div class="nav-links flex flex-col space-y-4 items-center w-screen bg-gray-200 dark:bg-gray-800 transition-all ease-out duration-300 h-0"> <div class="nav-links flex flex-col space-y-4 items-center w-screen bg-gray-200 dark:bg-gray-800 transition-all ease-out duration-500 h-0">
<!-- Current: "bg-gray-900 text-white", Default: "text-gray-300 hover:bg-gray-700 hover:text-white" --> <!-- Current: "bg-gray-900 text-white", Default: "text-gray-300 hover:bg-gray-700 hover:text-white" -->
{% for item in config.extra.navbar.items %} {% for item in config.extra.navbar.items %}
{% if lang == item.lang %} {% if lang == item.lang %}
{% for link in item.links %} {% for link in item.links %}
<a href="{{ link.url }}" class="text-gray-800 dark:text-gray-300 hover:bg-gray-700 hover:text-white px-3 py-2 rounded-md text-3xl hover:text-3xl font-medium">{{ link.name }}</a> <a href="{{ link.url }}" class="text-gray-800 dark:text-gray-300 hover:bg-gray-700 hover:text-white px-3 py-2 rounded-md text-sm font-medium">{{ link.name }}</a>
{% endfor %} {% endfor %}
{% endif %} {% endif %}
{% endfor %} {% endfor %}
@ -243,7 +244,7 @@
{% for item in config.extra.sidebar.items %} {% for item in config.extra.sidebar.items %}
{% if lang == item.lang %} {% if lang == item.lang %}
{% for link in item.links %} {% for link in item.links %}
<a href="{{ link.url }}" class="text-gray-800 dark:text-gray-300 hover:bg-gray-700 hover:text-white px-3 py-2 rounded-md text-3xl font-medium">{{ link.name }}</a> <a href="{{ link.url }}" class="text-gray-800 dark:text-gray-300 hover:bg-gray-700 hover:text-white px-3 py-2 rounded-md text-sm font-medium">{{ link.name }}</a>
{% endfor %} {% endfor %}
{% endif %} {% endif %}
{% endfor %} {% endfor %}
@ -254,7 +255,7 @@
<!-----------------------------------------------------------> <!----------------------------------------------------------->
<!------------------------- CONTENT -------------------------> <!------------------------- CONTENT ------------------------->
<!-----------------------------------------------------------> <!----------------------------------------------------------->
<main class="max-w-7xl mx-auto text-white bg-gray-200 dark:bg-gray-800 w-full mb-auto"> <main class="max-w-7xl mx-auto text-black dark:text-gray-200 w-full mb-auto">
{% block content %} {% block content %}
{% endblock content %} {% endblock content %}
</main> </main>
@ -307,7 +308,7 @@
<!------------------------- SCRIPTS -------------------------> <!------------------------- SCRIPTS ------------------------->
<script defer src="/js/main.js"></script> <script defer src="/js/main.js"></script>
{% if config.extra.enable_search %} {% if config.extra.enable_search %}
<script src="/js/elasticlunr.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/elasticlunr/0.9.6/elasticlunr.min.js"></script>
<script src="/search_index.{{lang}}.js"></script> <script src="/search_index.{{lang}}.js"></script>
<script defer src="/js/search.js"></script> <script defer src="/js/search.js"></script>
{% endif %} {% endif %}
@ -321,7 +322,5 @@
{% block extra_js %} {% block extra_js %}
{% endblock extra_js %} {% endblock extra_js %}
<script src="https://unpkg.com/htmx.org@1.9.12" integrity="sha384-ujb1lZYygJmzgSwoxRggbCHcjc0rB2XoQrxeTUQyRjrOnlCoYta87iKBWq3EsdM2" crossorigin="anonymous"></script>
</body> </body>
</html> </html>

View file

@ -1,7 +1,8 @@
<a <a
class="rounded-lg text-white bg-blue-600 px-4 py-2 text-neutral !no-underline hover:!bg-blue-500 dark:bg-blue-800 dark:hover:!bg-blue-700" class="rounded-lg outline-2 text-white bg-blue-600 outline-blue-600 px-4 py-2 text-neutral !no-underline hover:!bg-blue-500 dark:bg-blue-800 dark:hover:!bg-blue-700"
{% if href %}href="{{ href }}"{% endif %} {% if href %}href="{{ href }}"{% endif %}
{% if target %}target="{{ target }}"{% endif %} {% if target %}target="{{ target }}"{% endif %}
role="button"> role="button"
>
<i>{{ body }}</i> <i>{{ body }}</i>
</a> </a>

View file

@ -121,6 +121,7 @@
<span class='inline-block text-[#f39] text-sm align-sub'>* required</span> <span class='inline-block text-[#f39] text-sm align-sub'>* required</span>
</label> </label>
<input type="email" id="parent-email" name="parent-email" <input type="email" id="parent-email" name="parent-email"
pattern="^[a-zA-Z0-9]+(?:\.[a-zA-Z0-9]+)*@[a-zA-Z0-9]+(?:\.[a-zA-Z0-9]+)*$"
class="basis-full peer form-input class="basis-full peer form-input
{{ formClasses }} {{ formClasses }}
invalid:text-[#F39] invalid:text-[#F39]

View file

@ -57,6 +57,7 @@
<label for="email" class="basis-full">Your Email <span class='inline-block text-[#f39] text-sm align-sub'>* required</span></label> <label for="email" class="basis-full">Your Email <span class='inline-block text-[#f39] text-sm align-sub'>* required</span></label>
<input type="email" id="email" name="email" <input type="email" id="email" name="email"
pattern="^[a-zA-Z0-9]+(?:\.[a-zA-Z0-9]+)*@[a-zA-Z0-9]+(?:\.[a-zA-Z0-9]+)*$"
placeholder="bob@frank.xyz" placeholder="bob@frank.xyz"
class="basis-full form-input {{ formClasses }}"> class="basis-full form-input {{ formClasses }}">

View file

@ -1,4 +1,4 @@
<div class="mt-10"> <div class="mt-20">
<h1>Disciplemaking</h1> <h1>Disciplemaking</h1>
<div class="mb-8">TFCs core value is to follow the example of Jesus whose strategy of disciplemaking allowed Him to minister to all levels of spiritual interest at all times. These are those levels and where we work to reach teens at those levels. Everything we do is built around a desire to impact lives at each of these levels and help teenagers move forward through them.</div> <div class="mb-8">TFCs core value is to follow the example of Jesus whose strategy of disciplemaking allowed Him to minister to all levels of spiritual interest at all times. These are those levels and where we work to reach teens at those levels. Everything we do is built around a desire to impact lives at each of these levels and help teenagers move forward through them.</div>

View file

@ -25,7 +25,7 @@ homepage = "https://tchartron.com"
# Use snake_casing to be consistent with the rest of Zola # Use snake_casing to be consistent with the rest of Zola
[extra] [extra]
enable_search = true enable_search = true
enable_sidebar = false enable_sidebar = true
enable_adsense = true enable_adsense = true
enable_multilingue = true enable_multilingue = true
adsense_link = "https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=myclientid" adsense_link = "https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=myclientid"