Compare commits
4 commits
1b656dc834
...
ee252aec13
Author | SHA1 | Date | |
---|---|---|---|
![]() |
ee252aec13 | ||
![]() |
774328aa5b | ||
![]() |
845817d0e9 | ||
![]() |
23156940c0 |
19 changed files with 427 additions and 149 deletions
117
Cargo.lock
generated
117
Cargo.lock
generated
|
@ -335,6 +335,56 @@ dependencies = [
|
|||
"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]]
|
||||
name = "anyhow"
|
||||
version = "1.0.98"
|
||||
|
@ -639,6 +689,46 @@ dependencies = [
|
|||
"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]]
|
||||
name = "color-eyre"
|
||||
version = "0.6.5"
|
||||
|
@ -666,6 +756,12 @@ dependencies = [
|
|||
"tracing-error",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "colorchoice"
|
||||
version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75"
|
||||
|
||||
[[package]]
|
||||
name = "concurrent-queue"
|
||||
version = "2.5.0"
|
||||
|
@ -1624,6 +1720,12 @@ dependencies = [
|
|||
"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]]
|
||||
name = "itoa"
|
||||
version = "1.0.15"
|
||||
|
@ -2030,6 +2132,12 @@ version = "1.21.3"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
|
||||
|
||||
[[package]]
|
||||
name = "once_cell_polyfill"
|
||||
version = "1.70.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a4895175b425cb1f87721b59f0f286c2092bd4af812243672510e1ac53e2e0ad"
|
||||
|
||||
[[package]]
|
||||
name = "openssl"
|
||||
version = "0.10.73"
|
||||
|
@ -3094,7 +3202,7 @@ dependencies = [
|
|||
]
|
||||
|
||||
[[package]]
|
||||
name = "tfcapi"
|
||||
name = "tfcsite"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"actix-cors",
|
||||
|
@ -3103,6 +3211,7 @@ dependencies = [
|
|||
"actix-rt",
|
||||
"actix-web",
|
||||
"async-std",
|
||||
"clap",
|
||||
"color-eyre",
|
||||
"env_logger",
|
||||
"futures",
|
||||
|
@ -3479,6 +3588,12 @@ version = "1.0.4"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be"
|
||||
|
||||
[[package]]
|
||||
name = "utf8parse"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
|
||||
|
||||
[[package]]
|
||||
name = "uuid"
|
||||
version = "1.17.0"
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
[package]
|
||||
name = "tfcapi"
|
||||
name = "tfcsite"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
|
@ -32,6 +32,7 @@ tracing-actix-web = "0.7.14"
|
|||
color-eyre = "0.6.3"
|
||||
pretty_assertions = "1.4.1"
|
||||
sqlx = { version = "0.8.2", features = ["sqlite"] }
|
||||
clap = { version = "4.5.40", features = ["derive"] }
|
||||
|
||||
[profile.dev]
|
||||
opt-level = 0
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
# 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.
|
||||
title = "TFC Connection"
|
||||
|
@ -123,7 +125,7 @@ include_content = true
|
|||
# become too big to load on the site. Defaults to not being set.
|
||||
truncate_content_length = 100
|
||||
|
||||
index_format = "elasticlunr_json"
|
||||
index_format = "elasticlunr_javascript"
|
||||
|
||||
# Optional translation object for the default language
|
||||
# Example:
|
||||
|
@ -160,6 +162,7 @@ taxonomies = [
|
|||
#
|
||||
[extra]
|
||||
enable_search = true
|
||||
enable_sidebar = false
|
||||
|
||||
|
||||
[extra.navbar]
|
||||
|
|
|
@ -22,10 +22,10 @@ Fill out now!
|
|||
</span>
|
||||
</div>
|
||||
|
||||
{{ spacing(height="h-4") }}
|
||||
{{ spacing(height="h-8") }}
|
||||
|
||||
> 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).
|
||||
|
||||
{{ spacing(height="h-8") }}
|
||||
|
|
16
flake.nix
16
flake.nix
|
@ -66,15 +66,13 @@
|
|||
# cp -r ${blowfish} themes/blowfish
|
||||
# ls themes/blowfish
|
||||
# '';
|
||||
# buildPhase = ''
|
||||
# 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.hugo}/bin/hugo --minify
|
||||
# '';
|
||||
# installPhase = ''
|
||||
# ls -l
|
||||
# cp -r public $out/
|
||||
# ls -l $out
|
||||
# '';
|
||||
buildPhase = ''
|
||||
${pkgs.tailwindcss_4}/bin/tailwindcss -i static/css/base.css -o static/css/main.css
|
||||
${pkgs.zola}/bin/zola build
|
||||
'';
|
||||
installPhase = ''
|
||||
cp -r public $out/
|
||||
'';
|
||||
buildInputs = bi;
|
||||
nativeBuildInputs = nbi;
|
||||
};
|
||||
|
|
4
justfile
4
justfile
|
@ -3,7 +3,7 @@ default:
|
|||
build:
|
||||
tailwindcss -i static/css/base.css -o static/css/main.css && zola build
|
||||
serve:
|
||||
zola serve
|
||||
zola serve -p 4242
|
||||
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
|
||||
dev:
|
||||
|
@ -14,3 +14,5 @@ clean:
|
|||
cargo clean
|
||||
test:
|
||||
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
|
||||
|
|
|
@ -6,8 +6,8 @@ use color_eyre::eyre::{Context, Result};
|
|||
use futures::FutureExt;
|
||||
use lettre::{message::SinglePart, Message};
|
||||
use maud::{html, Markup, DOCTYPE};
|
||||
use reqwest::Client;
|
||||
use tracing::{error, info};
|
||||
use reqwest::{Client, Response};
|
||||
use tracing::{debug, error, info};
|
||||
|
||||
#[derive(Debug, MultipartForm)]
|
||||
struct CampForm {
|
||||
|
@ -39,27 +39,30 @@ struct CampForm {
|
|||
health_form: Text<String>,
|
||||
}
|
||||
|
||||
impl From<&CampForm> for HashMap<i32, String> {
|
||||
impl From<&CampForm> for HashMap<&str, String> {
|
||||
fn from(form: &CampForm) -> Self {
|
||||
let mut map = HashMap::new();
|
||||
map.insert(63, format!("{} {}", form.first_name.0, form.last_name.0));
|
||||
map.insert(
|
||||
64,
|
||||
"Full_Name",
|
||||
format!("{} {}", form.first_name.0, form.last_name.0),
|
||||
);
|
||||
map.insert(
|
||||
"Parent_Name",
|
||||
format!("{} {}", form.parent_first_name.0, form.parent_last_name.0),
|
||||
);
|
||||
map.insert(65, form.parent_phone.0.clone());
|
||||
map.insert(66, form.parent_email.0.clone().clone());
|
||||
map.insert(67, form.birthdate.0.clone());
|
||||
map.insert(69, form.gender.0.clone());
|
||||
map.insert(70, form.street.0.clone());
|
||||
map.insert(71, form.city.0.clone());
|
||||
map.insert(72, form.state.0.clone());
|
||||
map.insert(73, form.zip.0.clone().to_string());
|
||||
map.insert(74, form.grade.0.clone());
|
||||
map.insert(75, form.week.0.clone());
|
||||
map.insert(76, form.shirt.0.clone());
|
||||
map.insert(77, form.registration.0.clone());
|
||||
map.insert(115, form.health_form.0.clone());
|
||||
map.insert("Parent_Phone", form.parent_phone.0.clone());
|
||||
map.insert("Parent_Email", form.parent_email.0.clone().clone());
|
||||
map.insert("Birth_Date", form.birthdate.0.clone());
|
||||
map.insert("Gender", form.gender.0.clone());
|
||||
map.insert("Street_Address", form.street.0.clone());
|
||||
map.insert("City", form.city.0.clone());
|
||||
map.insert("State", form.state.0.clone());
|
||||
map.insert("Zipcode", form.zip.0.clone().to_string());
|
||||
map.insert("Grade", form.grade.0.clone());
|
||||
map.insert("Week_Chosen", form.week.0.clone());
|
||||
map.insert("Shirt_Size", form.shirt.0.clone());
|
||||
map.insert("Registration", form.registration.0.clone());
|
||||
map.insert("Health_Form", form.health_form.0.clone());
|
||||
map
|
||||
}
|
||||
}
|
||||
|
@ -292,19 +295,21 @@ pub async fn camp_form(MultipartForm(form): MultipartForm<CampForm>) -> HttpResp
|
|||
}
|
||||
}
|
||||
|
||||
async fn store_camp_form(map: HashMap<i32, String>) -> Result<()> {
|
||||
async fn store_camp_form(map: HashMap<&str, String>) -> Result<Response> {
|
||||
let request = Client::new();
|
||||
let mut json = HashMap::new();
|
||||
json.insert("data", map);
|
||||
request
|
||||
.post("https://staff.tfcconnection.org/apps/tables/api/1/tables/5/rows")
|
||||
.basic_auth("chris", Some("2VHeGxeC^Zf9KqFK^G@Pt!zu2q^6@b"))
|
||||
.header("OCS-APIRequest", "true")
|
||||
let mut fields = HashMap::new();
|
||||
fields.insert("fields", map);
|
||||
json.insert("records", vec![fields]);
|
||||
let response = request
|
||||
.post("https://table.tfcconnection.org/api/docs/e8SFoTHpmJuFQsiMhRTXCi/tables/Camp_Data/records")
|
||||
.bearer_auth("b8189d1b315548aa610db2fd3a43177a967cd41f")
|
||||
.header("Content-Type", "application/json")
|
||||
.json(&json)
|
||||
.send()
|
||||
.await?;
|
||||
Ok(())
|
||||
debug!(?response);
|
||||
Ok(response)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
@ -329,7 +334,7 @@ mod test {
|
|||
grade: Text(String::from("junior")),
|
||||
shirt: Text(String::from("medium")),
|
||||
allergies: Text(String::from("Cool beans")),
|
||||
week: Text(String::from("1")),
|
||||
week: Text(String::from("week1")),
|
||||
registration: Text(String::from("later")),
|
||||
health_form: Text(String::from("I guess")),
|
||||
}
|
||||
|
@ -342,7 +347,7 @@ mod test {
|
|||
let map = HashMap::from(&form);
|
||||
let res = store_camp_form(map).await;
|
||||
match res {
|
||||
Ok(_) => assert!(true),
|
||||
Ok(r) => assert!(r.status().is_success(), "Failed to store: {:?}", r),
|
||||
Err(e) => assert!(false, "Failed storing test: {e}"),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ use lettre::{
|
|||
Message,
|
||||
};
|
||||
use maud::{html, Markup, DOCTYPE};
|
||||
use reqwest::Client;
|
||||
use reqwest::{Client, Response};
|
||||
use tracing::{error, info};
|
||||
|
||||
use crate::email::send_email;
|
||||
|
@ -75,40 +75,46 @@ struct HealthForm {
|
|||
registration: Text<String>,
|
||||
}
|
||||
|
||||
impl From<&HealthForm> for HashMap<i32, String> {
|
||||
impl From<&HealthForm> for HashMap<&str, String> {
|
||||
fn from(form: &HealthForm) -> Self {
|
||||
let mut map = HashMap::new();
|
||||
map.insert(37, format!("{} {}", form.first_name.0, form.last_name.0));
|
||||
map.insert(
|
||||
38,
|
||||
"Student_Name",
|
||||
format!("{} {}", form.first_name.0, form.last_name.0),
|
||||
);
|
||||
map.insert(
|
||||
"Parent_Name",
|
||||
format!("{} {}", form.parent_first_name.0, form.parent_last_name.0),
|
||||
);
|
||||
map.insert(39, form.birthdate.0.clone());
|
||||
map.insert(40, form.street.0.clone());
|
||||
map.insert(41, form.city.0.clone());
|
||||
map.insert(42, form.state.0.clone());
|
||||
map.insert(43, form.zip.0.clone());
|
||||
map.insert(44, form.parent_cellphone.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("Birthdate", form.birthdate.0.clone());
|
||||
map.insert("Street", form.street.0.clone());
|
||||
map.insert("City", form.city.0.clone());
|
||||
map.insert("State", form.state.0.clone());
|
||||
map.insert("Zipcode", form.zip.0.clone());
|
||||
map.insert("Parent_Phone", form.parent_cellphone.0.clone());
|
||||
map.insert("Homephone", form.homephone.0.clone());
|
||||
map.insert(
|
||||
55,
|
||||
"Emergency_Contact",
|
||||
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),
|
||||
);
|
||||
map.insert(56, form.specific_allergies.0.clone());
|
||||
map.insert(57, form.treatment.0.clone());
|
||||
map.insert(58, form.conditions.0.clone());
|
||||
map.insert(59, form.tetanus.0.clone());
|
||||
map.insert(60, form.medication.0.clone());
|
||||
map.insert(61, form.notes.0.clone());
|
||||
map.insert(62, form.swimming.0.clone());
|
||||
map.insert("Specific_Allergies", form.specific_allergies.0.clone());
|
||||
map.insert("Allergic_Treatments", form.treatment.0.clone());
|
||||
map.insert("Conditions", form.conditions.0.clone());
|
||||
map.insert("Tetanus_Shot_Date", form.tetanus.0.clone());
|
||||
map.insert("Medication_Schedule", form.medication.0.clone());
|
||||
map.insert("Other_Notes", form.notes.0.clone());
|
||||
map.insert("Swimming_Ability", form.swimming.0.clone());
|
||||
map
|
||||
}
|
||||
}
|
||||
|
@ -431,22 +437,22 @@ pub async fn health_form(MultipartForm(mut form): MultipartForm<HealthForm>) ->
|
|||
// HttpResponse::Ok().body("hi")
|
||||
}
|
||||
|
||||
async fn store_form(map: HashMap<i32, String>) -> Result<()> {
|
||||
async fn store_form(map: HashMap<&str, String>) -> Result<Response> {
|
||||
let client = Client::new();
|
||||
let mut json = HashMap::new();
|
||||
json.insert("data", map);
|
||||
let mut fields = HashMap::new();
|
||||
fields.insert("fields", map);
|
||||
json.insert("records", vec![fields]);
|
||||
|
||||
let res = client
|
||||
.post("https://staff.tfcconnection.org/ocs/v2.php/apps/tables/api/2/tables/4/rows")
|
||||
.basic_auth("chris", Some("2VHeGxeC^Zf9KqFK^G@Pt!zu2q^6@b"))
|
||||
.header("OCS-APIRequest", "true")
|
||||
.post("https://table.tfcconnection.org/api/docs/e8SFoTHpmJuFQsiMhRTXCi/tables/Health_Data/records")
|
||||
.bearer_auth("b8189d1b315548aa610db2fd3a43177a967cd41f")
|
||||
.header("Content-Type", "application/json")
|
||||
.json(&json)
|
||||
.send()
|
||||
.await?;
|
||||
if res.status().is_success() {
|
||||
let res = res.text().await.unwrap();
|
||||
Ok(())
|
||||
Ok(res)
|
||||
} else {
|
||||
Err(eyre!(
|
||||
"Problem in storing data: {:?}",
|
||||
|
@ -454,3 +460,69 @@ async fn store_form(map: HashMap<i32, String>) -> Result<()> {
|
|||
))
|
||||
}
|
||||
}
|
||||
|
||||
#[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}"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
62
src/main.rs
62
src/main.rs
|
@ -7,7 +7,7 @@ use actix_web::body::MessageBody;
|
|||
use actix_web::dev::{ServiceRequest, ServiceResponse};
|
||||
use actix_web::{web, App, Error, HttpServer};
|
||||
use api::camp_form::camp_form;
|
||||
use api::contact::{self, contact_form};
|
||||
use api::contact::contact_form;
|
||||
use api::health_form::health_form;
|
||||
use api::local_trip_form::local_form;
|
||||
use api::mt_form::mt_form;
|
||||
|
@ -15,6 +15,7 @@ use api::{
|
|||
mt_church_form::mt_church_form, mt_parent_form::mt_parent_form,
|
||||
mt_teacher_form::mt_teacher_form,
|
||||
};
|
||||
use clap::Parser;
|
||||
use color_eyre::eyre::Context;
|
||||
use color_eyre::Result;
|
||||
use sqlx::{Connection, SqliteConnection};
|
||||
|
@ -45,45 +46,64 @@ impl RootSpanBuilder for DomainRootSpanBuilder {
|
|||
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]
|
||||
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 =
|
||||
tracing_subscriber::fmt::time::ChronoLocal::new("%Y-%m-%d_%I:%M:%S%.6f %P".to_owned());
|
||||
let logfile = RollingFileAppender::builder()
|
||||
.rotation(Rotation::DAILY)
|
||||
.filename_prefix("api")
|
||||
.filename_suffix("log")
|
||||
.build(if DEV_MODE {
|
||||
"/tmp/tfcsite"
|
||||
} else {
|
||||
"/storage/logs/tfcsite"
|
||||
})
|
||||
.build(&logs)
|
||||
.expect("Shouldn't");
|
||||
|
||||
let filter = EnvFilter::builder()
|
||||
let file_filter = EnvFilter::builder()
|
||||
.with_default_directive(LevelFilter::WARN.into())
|
||||
.parse_lossy("tfcapi=debug");
|
||||
.parse_lossy("tfcsite=debug");
|
||||
let logfile_layer = tracing_subscriber::fmt::layer()
|
||||
.with_writer(logfile)
|
||||
.with_line_number(true)
|
||||
.with_level(true)
|
||||
.with_target(true)
|
||||
.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()
|
||||
.pretty()
|
||||
.with_line_number(true)
|
||||
.with_target(true)
|
||||
.with_timer(timer)
|
||||
.with_filter(filter);
|
||||
let filter = EnvFilter::builder()
|
||||
.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");
|
||||
.with_filter(stdout_filter);
|
||||
|
||||
std::fs::create_dir_all("/tmp/tfcsite")?;
|
||||
let subscriber = tracing_subscriber::registry().with(logfile_layer.and_then(stdout_layer));
|
||||
let _ = tracing::subscriber::set_global_default(subscriber).wrap_err("Tracing broked");
|
||||
|
||||
info!("starting HTTP server at http://localhost:4242");
|
||||
|
||||
|
@ -96,11 +116,7 @@ async fn main() -> std::io::Result<()> {
|
|||
App::new()
|
||||
.app_data(data.clone())
|
||||
.wrap(TracingLogger::<DomainRootSpanBuilder>::new())
|
||||
.app_data(TempFileConfig::default().directory(if DEV_MODE {
|
||||
"/tmp/tfcsite"
|
||||
} else {
|
||||
"/storage/logs/tfcsite"
|
||||
}))
|
||||
.app_data(TempFileConfig::default().directory(&temp))
|
||||
.service(mt_form)
|
||||
.service(health_form)
|
||||
.service(mt_parent_form)
|
||||
|
@ -109,7 +125,7 @@ async fn main() -> std::io::Result<()> {
|
|||
.service(local_form)
|
||||
.service(camp_form)
|
||||
.service(contact_form)
|
||||
.service(Files::new("/", "./public").index_file("index.html"))
|
||||
.service(Files::new("/", &site).index_file("index.html"))
|
||||
})
|
||||
.bind(("localhost", 4242))?
|
||||
.workers(4)
|
||||
|
|
|
@ -27,6 +27,17 @@
|
|||
li::marker {
|
||||
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 {
|
||||
@apply py-0;
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
'Noto Color Emoji';
|
||||
--font-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New',
|
||||
monospace;
|
||||
--color-blue-200: oklch(88.2% 0.059 254.128);
|
||||
--color-blue-400: oklch(70.7% 0.165 254.624);
|
||||
--color-blue-500: oklch(62.3% 0.214 259.815);
|
||||
--color-blue-600: oklch(54.6% 0.245 262.881);
|
||||
|
@ -351,9 +352,6 @@
|
|||
.mt-16 {
|
||||
margin-top: calc(var(--spacing) * 16);
|
||||
}
|
||||
.mt-20 {
|
||||
margin-top: calc(var(--spacing) * 20);
|
||||
}
|
||||
.mt-40 {
|
||||
margin-top: calc(var(--spacing) * 40);
|
||||
}
|
||||
|
@ -390,6 +388,9 @@
|
|||
.ml-4 {
|
||||
margin-left: calc(var(--spacing) * 4);
|
||||
}
|
||||
.ml-\[-0\.2em\] {
|
||||
margin-left: -0.2em;
|
||||
}
|
||||
.ml-auto {
|
||||
margin-left: auto;
|
||||
}
|
||||
|
@ -457,9 +458,6 @@
|
|||
.h-24 {
|
||||
height: calc(var(--spacing) * 24);
|
||||
}
|
||||
.h-36 {
|
||||
height: calc(var(--spacing) * 36);
|
||||
}
|
||||
.h-40 {
|
||||
height: calc(var(--spacing) * 40);
|
||||
}
|
||||
|
@ -767,9 +765,6 @@
|
|||
.bg-indigo-500 {
|
||||
background-color: var(--color-indigo-500);
|
||||
}
|
||||
.bg-transparent {
|
||||
background-color: transparent;
|
||||
}
|
||||
.bg-white {
|
||||
background-color: var(--color-white);
|
||||
}
|
||||
|
@ -947,9 +942,6 @@
|
|||
.text-gray-900 {
|
||||
color: var(--color-gray-900);
|
||||
}
|
||||
.text-indigo-500 {
|
||||
color: var(--color-indigo-500);
|
||||
}
|
||||
.text-white {
|
||||
color: var(--color-white);
|
||||
}
|
||||
|
@ -1020,9 +1012,6 @@
|
|||
--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 {
|
||||
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-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));
|
||||
|
@ -1198,13 +1187,6 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
.hover\:bg-gray-100 {
|
||||
&:hover {
|
||||
@media (hover: hover) {
|
||||
background-color: var(--color-gray-100);
|
||||
}
|
||||
}
|
||||
}
|
||||
.hover\:bg-gray-200 {
|
||||
&:hover {
|
||||
@media (hover: hover) {
|
||||
|
@ -1240,6 +1222,14 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
.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 {
|
||||
@media (hover: hover) {
|
||||
|
@ -1261,13 +1251,6 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
.hover\:text-indigo-400 {
|
||||
&:hover {
|
||||
@media (hover: hover) {
|
||||
color: var(--color-indigo-400);
|
||||
}
|
||||
}
|
||||
}
|
||||
.hover\:text-white {
|
||||
&:hover {
|
||||
@media (hover: hover) {
|
||||
|
@ -1628,6 +1611,11 @@
|
|||
background-color: var(--color-gray-900);
|
||||
}
|
||||
}
|
||||
.dark\:text-blue-200 {
|
||||
@media (prefers-color-scheme: dark) {
|
||||
color: var(--color-blue-200);
|
||||
}
|
||||
}
|
||||
.dark\:text-gray-200 {
|
||||
@media (prefers-color-scheme: dark) {
|
||||
color: var(--color-gray-200);
|
||||
|
@ -1716,6 +1704,16 @@
|
|||
li::marker {
|
||||
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 {
|
||||
padding-block: calc(var(--spacing) * 0);
|
||||
border-radius: var(--radius-lg);
|
||||
|
|
10
static/js/elasticlunr.min.js
vendored
Normal file
10
static/js/elasticlunr.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
|
@ -1,6 +1,55 @@
|
|||
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">
|
||||
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 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}">
|
||||
<span class="text-xl text-bold">${e.doc.title}</span>
|
||||
<span class="text-lg">${e.doc.description}</span>
|
||||
<span class="dark:text-white text-xl text-bold">${e.doc.title}</span>
|
||||
<br/>
|
||||
<span class="dark:text-blue-200 text-lg">${e.doc.description}</span>
|
||||
</a>
|
||||
</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)}}})});
|
||||
</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)
|
||||
}
|
||||
}
|
||||
})
|
||||
});
|
||||
|
|
|
@ -36,7 +36,7 @@
|
|||
{% endblock title %}
|
||||
</title>
|
||||
</head>
|
||||
<body class="dark:bg-gray-700 flex flex-col h-screen justify-between">
|
||||
<body class="dark:bg-gray-800 flex flex-col h-screen justify-between">
|
||||
<!---------------------------------------------------------->
|
||||
<!------------------------- 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 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-36 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-48 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">
|
||||
<svg class="fill-current text-white" xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 18 18">
|
||||
|
@ -141,8 +141,7 @@
|
|||
<ul id="results-list" class="flex flex-col justify-center max-h-2xl mt-2 overflow-scroll"></ul>
|
||||
<!--Footer-->
|
||||
<div class="flex justify-end pt-2">
|
||||
<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>
|
||||
<button class="px-4 bg-indigo-500 p-3 rounded-lg text-white hover:bg-indigo-400">Search</button>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
@ -230,12 +229,12 @@
|
|||
|
||||
<!----------------------------- Mobile menu ----------------------------->
|
||||
<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-500 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-300 h-0">
|
||||
<!-- Current: "bg-gray-900 text-white", Default: "text-gray-300 hover:bg-gray-700 hover:text-white" -->
|
||||
{% for item in config.extra.navbar.items %}
|
||||
{% if lang == item.lang %}
|
||||
{% 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-sm 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-3xl hover:text-3xl font-medium">{{ link.name }}</a>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
@ -244,7 +243,7 @@
|
|||
{% for item in config.extra.sidebar.items %}
|
||||
{% if lang == item.lang %}
|
||||
{% 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-sm 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-3xl font-medium">{{ link.name }}</a>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
@ -255,7 +254,7 @@
|
|||
<!----------------------------------------------------------->
|
||||
<!------------------------- CONTENT ------------------------->
|
||||
<!----------------------------------------------------------->
|
||||
<main class="max-w-7xl mx-auto text-black dark:text-gray-200 w-full mb-auto">
|
||||
<main class="max-w-7xl mx-auto text-white bg-gray-200 dark:bg-gray-800 w-full mb-auto">
|
||||
{% block content %}
|
||||
{% endblock content %}
|
||||
</main>
|
||||
|
@ -308,7 +307,7 @@
|
|||
<!------------------------- SCRIPTS ------------------------->
|
||||
<script defer src="/js/main.js"></script>
|
||||
{% if config.extra.enable_search %}
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/elasticlunr/0.9.6/elasticlunr.min.js"></script>
|
||||
<script src="/js/elasticlunr.min.js"></script>
|
||||
<script src="/search_index.{{lang}}.js"></script>
|
||||
<script defer src="/js/search.js"></script>
|
||||
{% endif %}
|
||||
|
@ -322,5 +321,7 @@
|
|||
{% block extra_js %}
|
||||
{% endblock extra_js %}
|
||||
|
||||
<script src="https://unpkg.com/htmx.org@1.9.12" integrity="sha384-ujb1lZYygJmzgSwoxRggbCHcjc0rB2XoQrxeTUQyRjrOnlCoYta87iKBWq3EsdM2" crossorigin="anonymous"></script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
<a
|
||||
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"
|
||||
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"
|
||||
{% if href %}href="{{ href }}"{% endif %}
|
||||
{% if target %}target="{{ target }}"{% endif %}
|
||||
role="button"
|
||||
>
|
||||
role="button">
|
||||
<i>{{ body }}</i>
|
||||
</a>
|
||||
|
|
|
@ -121,7 +121,6 @@
|
|||
<span class='inline-block text-[#f39] text-sm align-sub'>* required</span>
|
||||
</label>
|
||||
<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
|
||||
{{ formClasses }}
|
||||
invalid:text-[#F39]
|
||||
|
|
|
@ -57,7 +57,6 @@
|
|||
|
||||
<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"
|
||||
pattern="^[a-zA-Z0-9]+(?:\.[a-zA-Z0-9]+)*@[a-zA-Z0-9]+(?:\.[a-zA-Z0-9]+)*$"
|
||||
placeholder="bob@frank.xyz"
|
||||
class="basis-full form-input {{ formClasses }}">
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<div class="mt-20">
|
||||
<div class="mt-10">
|
||||
<h1>Disciplemaking</h1>
|
||||
<div class="mb-8">TFC’s 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>
|
||||
|
||||
|
|
|
@ -25,7 +25,7 @@ homepage = "https://tchartron.com"
|
|||
# Use snake_casing to be consistent with the rest of Zola
|
||||
[extra]
|
||||
enable_search = true
|
||||
enable_sidebar = true
|
||||
enable_sidebar = false
|
||||
enable_adsense = true
|
||||
enable_multilingue = true
|
||||
adsense_link = "https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=myclientid"
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue