Compare commits

..

21 Commits

Author SHA1 Message Date
7c81d11e32 fix(okd-recover-from-expired-certs): remove wrong og:image tag 2024-07-02 15:10:01 -04:00
dc46da4ce2 fix(okd-recover-from-expired-certs): RedHat -> Red Hat 2024-06-29 19:22:11 -04:00
3181e0db9e forgot the build_docker step 2024-06-29 19:09:08 -04:00
37b1ed8fe3 bump version to deploy 2024-06-29 18:59:40 -04:00
2ecf37220a feat: expired certs blog 2024-06-29 18:50:54 -04:00
19dd198506 feat(OkdInstallBlog): add missing subscription config 2024-04-20 10:53:05 -04:00
900b920966 feat(OkdInstallBlog): fix (3nd try) image size... 2024-04-20 10:13:41 -04:00
67e9edde5d feat(OkdInstallBlog): fix (2nd try) og tags for linkedIn 2024-04-20 09:56:45 -04:00
464c1506d6 feat(OkdInstallBlog): fix (hopefully) og tags for linkedIn 2024-04-20 09:39:23 -04:00
d65230faf0 feat(OkdInstallBlog): add og tag for linkedin preview 2024-04-20 09:14:20 -04:00
eca9bc5c24 feat(OkdInstallBlog): bump version to deploy 2024-04-20 08:28:13 -04:00
e4d50dca2a feat(OkdInstallBlog): Add references section and some light changes in my description 2024-04-20 08:27:38 -04:00
17465f341b New version with OKD blog part 1 2024-04-19 08:11:13 -04:00
caf90d7a95 feat(sreez): Improve subscribe look, integrate it on the blog page 2024-04-17 22:44:58 -04:00
jeangab
3bcb92829a feat(sreez): Add subscribe button that sends a notification to discord 2024-04-17 16:44:25 -04:00
acbc8a20d6 feat(okdInstallationBlog): wip part 1 2024-04-17 15:33:16 -04:00
9ce21abd74 feat(okdInstallationBlog): wip part 1 (#1)
Reviewed-on: http://gitea.wk.nt.local:31080/johnride/nationtech-website/pulls/1
Co-authored-by: Sylvain Tremblay <stremblay@nationtech.io>
Co-committed-by: Sylvain Tremblay <stremblay@nationtech.io>
2024-04-17 16:58:35 +00:00
jeangab
d72f4212a3 feat(sreez): Upgrade sreez website to 1.2.0 2024-04-15 10:12:12 -04:00
jeangab
225bb7bbe2 feat(sreez): Add og:image on landing page 2024-04-15 10:01:38 -04:00
Jean-Gabriel Gill-Couture
075dc2ac0c chore(sreez): Bump version to v1.1.0 2024-04-12 23:46:40 -04:00
Jean-Gabriel Gill-Couture
1616c9abaa feat(sreez): Improve the landing page 2024-04-12 23:39:36 -04:00
29 changed files with 1249 additions and 87 deletions

2
.gitignore vendored
View File

@@ -11,3 +11,5 @@ node_modules/
test-results/
end2end/playwright-report/
playwright/.cache/
venv

View File

@@ -8,10 +8,10 @@ image:
repository: registry.nationtech.io/sreez-website
pullPolicy: Always
# Overrides the image tag whose default is the chart appVersion.
tag: "v1.0.0"
tag: "v1.8.2"
imagePullSecrets:
- name: nationtech-registry-key
- name: nationtech-registry-key
nameOverride: ""
fullnameOverride: ""
@@ -53,14 +53,14 @@ ingress:
# kubernetes.io/ingress.class: nginx
# kubernetes.io/tls-acme: "true"
hosts:
- host: sreez.nationtech.io
paths:
- path: /
pathType: ImplementationSpecific
- host: sreez.nationtech.io
paths:
- path: /
pathType: ImplementationSpecific
tls:
- secretName: sreez.nationtech.io-tls
hosts:
- sreez.nationtech.io
- secretName: sreez.nationtech.io-tls
hosts:
- sreez.nationtech.io
resources: {}
# We usually recommend not to specify default resources and to leave this as a conscious

34
helm/tools/update_yaml.py Normal file
View File

@@ -0,0 +1,34 @@
import sys
from ruamel.yaml import YAML
def update_yaml(file_path, path_to_update, new_value):
yaml = YAML()
yaml.preserve_quotes = True # Optional, to preserve the original quotation marks
# Load the YAML file
with open(file_path, 'r') as file:
data = yaml.load(file)
# Split the path to navigate through the YAML structure
keys = path_to_update.strip('.').split('.')
# Access the nested dictionary and update the value
temp = data
for key in keys[:-1]:
temp = temp[key]
temp[keys[-1]] = new_value
# Write the YAML file back
with open(file_path, 'w') as file:
yaml.dump(data, file)
if __name__ == "__main__":
if len(sys.argv) != 4:
print("Usage: python update_yaml.py <path/to/file.yaml> <.path.to.key> <new_value>")
sys.exit(1)
file_path = sys.argv[1]
path_to_update = sys.argv[2]
new_value = sys.argv[3]
update_yaml(file_path, path_to_update, new_value)

261
sreez/Cargo.lock generated
View File

@@ -142,6 +142,27 @@ dependencies = [
"pin-project-lite",
]
[[package]]
name = "actix-tls"
version = "3.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d4cce60a2f2b477bc72e5cde0af1812a6e82d8fd85b5570a5dcf2a5bf2c5be5f"
dependencies = [
"actix-rt",
"actix-service",
"actix-utils",
"futures-core",
"http 0.2.12",
"http 1.1.0",
"impl-more",
"pin-project-lite",
"tokio",
"tokio-rustls",
"tokio-util",
"tracing",
"webpki-roots",
]
[[package]]
name = "actix-utils"
version = "3.0.1"
@@ -262,6 +283,21 @@ version = "0.2.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f"
[[package]]
name = "android-tzdata"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0"
[[package]]
name = "android_system_properties"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311"
dependencies = [
"libc",
]
[[package]]
name = "anyhow"
version = "1.0.82"
@@ -315,6 +351,40 @@ version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f1fdabc7756949593fe60f30ec81974b613357de856987752631dea1e3394c80"
[[package]]
name = "awc"
version = "3.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "68c09cc97310b926f01621faee652f3d1b0962545a3cec6c9ac07def9ea36c2c"
dependencies = [
"actix-codec",
"actix-http",
"actix-rt",
"actix-service",
"actix-tls",
"actix-utils",
"base64 0.21.7",
"bytes",
"cfg-if",
"cookie",
"derive_more",
"futures-core",
"futures-util",
"h2",
"http 0.2.12",
"itoa",
"log",
"mime",
"percent-encoding",
"pin-project-lite",
"rand",
"rustls",
"serde",
"serde_json",
"serde_urlencoded",
"tokio",
]
[[package]]
name = "backtrace"
version = "0.3.71"
@@ -459,6 +529,20 @@ version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "chrono"
version = "0.4.38"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401"
dependencies = [
"android-tzdata",
"iana-time-zone",
"js-sys",
"num-traits",
"wasm-bindgen",
"windows-targets 0.52.5",
]
[[package]]
name = "ciborium"
version = "0.2.2"
@@ -562,6 +646,12 @@ dependencies = [
"version_check",
]
[[package]]
name = "core-foundation-sys"
version = "0.8.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f"
[[package]]
name = "cpufeatures"
version = "0.2.12"
@@ -985,6 +1075,29 @@ version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9"
[[package]]
name = "iana-time-zone"
version = "0.1.60"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141"
dependencies = [
"android_system_properties",
"core-foundation-sys",
"iana-time-zone-haiku",
"js-sys",
"wasm-bindgen",
"windows-core",
]
[[package]]
name = "iana-time-zone-haiku"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f"
dependencies = [
"cc",
]
[[package]]
name = "ident_case"
version = "1.0.1"
@@ -1001,6 +1114,12 @@ dependencies = [
"unicode-normalization",
]
[[package]]
name = "impl-more"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "206ca75c9c03ba3d4ace2460e57b189f39f43de612c2f85836e65c929701bb2d"
[[package]]
name = "indexmap"
version = "2.2.6"
@@ -1452,6 +1571,15 @@ version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9"
[[package]]
name = "num-traits"
version = "0.2.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a"
dependencies = [
"autocfg",
]
[[package]]
name = "object"
version = "0.32.2"
@@ -1730,6 +1858,36 @@ version = "0.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "adad44e29e4c806119491a7f06f03de4d1af22c3a680dd47f1e6e179439d1f56"
[[package]]
name = "ring"
version = "0.16.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc"
dependencies = [
"cc",
"libc",
"once_cell",
"spin 0.5.2",
"untrusted 0.7.1",
"web-sys",
"winapi",
]
[[package]]
name = "ring"
version = "0.17.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d"
dependencies = [
"cc",
"cfg-if",
"getrandom",
"libc",
"spin 0.9.8",
"untrusted 0.9.0",
"windows-sys 0.52.0",
]
[[package]]
name = "rstml"
version = "0.11.2"
@@ -1765,6 +1923,18 @@ dependencies = [
"semver",
]
[[package]]
name = "rustls"
version = "0.20.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1b80e3dec595989ea8510028f30c408a4630db12c9cbb8de34203b89d6577e99"
dependencies = [
"log",
"ring 0.16.20",
"sct",
"webpki",
]
[[package]]
name = "ryu"
version = "1.0.17"
@@ -1786,6 +1956,16 @@ version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
[[package]]
name = "sct"
version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414"
dependencies = [
"ring 0.17.8",
"untrusted 0.9.0",
]
[[package]]
name = "self_cell"
version = "1.0.3"
@@ -1809,9 +1989,9 @@ dependencies = [
[[package]]
name = "serde"
version = "1.0.197"
version = "1.0.198"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2"
checksum = "9846a40c979031340571da2545a4e5b7c4163bdae79b301d5f86d03979451fcc"
dependencies = [
"serde_derive",
]
@@ -1829,9 +2009,9 @@ dependencies = [
[[package]]
name = "serde_derive"
version = "1.0.197"
version = "1.0.198"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b"
checksum = "e88edab869b01783ba905e7d0153f9fc1a6505a96e4ad3018011eedb838566d9"
dependencies = [
"proc-macro2",
"quote",
@@ -1840,9 +2020,9 @@ dependencies = [
[[package]]
name = "serde_json"
version = "1.0.115"
version = "1.0.116"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "12dc5c46daa8e9fdf4f5e71b6cf9a53f2487da0e86e55808e2d35539666497dd"
checksum = "3e17db7126d17feb94eb3fad46bf1a96b034e8aacbc2e775fe81505f8b0b2813"
dependencies = [
"itoa",
"ryu",
@@ -2000,18 +2180,36 @@ dependencies = [
"windows-sys 0.52.0",
]
[[package]]
name = "spin"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d"
[[package]]
name = "spin"
version = "0.9.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67"
[[package]]
name = "sreez"
version = "0.1.0"
dependencies = [
"actix-files",
"actix-web",
"awc",
"chrono",
"console_error_panic_hook",
"http 0.2.12",
"leptos",
"leptos_actix",
"leptos_meta",
"leptos_router",
"regex",
"serde",
"serde_json",
"toml",
"wasm-bindgen",
]
@@ -2138,6 +2336,17 @@ dependencies = [
"windows-sys 0.48.0",
]
[[package]]
name = "tokio-rustls"
version = "0.23.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c43ee83903113e03984cb9e5cebe6c04a5116269e900e3ddba8f068a62adda59"
dependencies = [
"rustls",
"tokio",
"webpki",
]
[[package]]
name = "tokio-util"
version = "0.7.10"
@@ -2286,6 +2495,18 @@ version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c"
[[package]]
name = "untrusted"
version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a"
[[package]]
name = "untrusted"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1"
[[package]]
name = "url"
version = "2.5.0"
@@ -2429,6 +2650,25 @@ dependencies = [
"wasm-bindgen",
]
[[package]]
name = "webpki"
version = "0.22.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ed63aea5ce73d0ff405984102c42de94fc55a6b75765d621c65262469b3c9b53"
dependencies = [
"ring 0.17.8",
"untrusted 0.9.0",
]
[[package]]
name = "webpki-roots"
version = "0.22.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b6c71e40d7d2c34a5106301fb632274ca37242cd0c9d3e64dbece371a40a2d87"
dependencies = [
"webpki",
]
[[package]]
name = "winapi"
version = "0.3.9"
@@ -2460,6 +2700,15 @@ version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
[[package]]
name = "windows-core"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9"
dependencies = [
"windows-targets 0.52.5",
]
[[package]]
name = "windows-sys"
version = "0.48.0"

View File

@@ -16,6 +16,12 @@ leptos_meta = { version = "0.6", features = ["nightly"] }
leptos_actix = { version = "0.6", optional = true }
leptos_router = { version = "0.6", features = ["nightly"] }
wasm-bindgen = "=0.2.92"
toml = "0.8.12"
serde = "1.0.198"
chrono = "0.4.38"
awc = { version = "3.4.0", optional = true, features = ["rustls"] }
serde_json = { version = "1.0.116", optional = true }
regex = "1.10.4"
[features]
csr = ["leptos/csr", "leptos_meta/csr", "leptos_router/csr"]
@@ -27,7 +33,10 @@ ssr = [
"leptos/ssr",
"leptos_meta/ssr",
"leptos_router/ssr",
"awc",
"serde_json",
]
awc = ["dep:awc"]
# Defines a size-optimized profile for the WASM bundle in release mode
[profile.wasm-release]

View File

@@ -43,6 +43,9 @@ COPY --from=builder /app/target/site /app/site
# Copy Cargo.toml if its needed at runtime
COPY --from=builder /app/Cargo.toml /app/
# Copy config.toml to configure discord endpoint
COPY --from=builder /app/config.toml /app/
# Set any required env variables and
ENV RUST_LOG="info"
ENV LEPTOS_SITE_ADDR="0.0.0.0:8080"

BIN
sreez/assets/OKD4.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 214 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 83 KiB

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 127.14 96.36"><g id="图层_2" data-name="图层 2"><g id="Discord_Logos" data-name="Discord Logos"><g id="Discord_Logo_-_Large_-_White" data-name="Discord Logo - Large - White"><path d="M107.7,8.07A105.15,105.15,0,0,0,81.47,0a72.06,72.06,0,0,0-3.36,6.83A97.68,97.68,0,0,0,49,6.83,72.37,72.37,0,0,0,45.64,0,105.89,105.89,0,0,0,19.39,8.09C2.79,32.65-1.71,56.6.54,80.21h0A105.73,105.73,0,0,0,32.71,96.36,77.7,77.7,0,0,0,39.6,85.25a68.42,68.42,0,0,1-10.85-5.18c.91-.66,1.8-1.34,2.66-2a75.57,75.57,0,0,0,64.32,0c.87.71,1.76,1.39,2.66,2a68.68,68.68,0,0,1-10.87,5.19,77,77,0,0,0,6.89,11.1A105.25,105.25,0,0,0,126.6,80.22h0C129.24,52.84,122.09,29.11,107.7,8.07ZM42.45,65.69C36.18,65.69,31,60,31,53s5-12.74,11.43-12.74S54,46,53.89,53,48.84,65.69,42.45,65.69Zm42.24,0C78.41,65.69,73.25,60,73.25,53s5-12.74,11.44-12.74S96.23,46,96.12,53,91.08,65.69,84.69,65.69Z"/></g></g></g></svg>

After

Width:  |  Height:  |  Size: 925 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 93 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 143 KiB

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 143 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 105 KiB

View File

@@ -1,18 +1,19 @@
#!/bin/bash
if [[ -z "${1}" ]]
then
echo "Specify the image tag as first argument to this script"
exit 1
fi
REGISTRY=registry.nationtech.io
IMAGE_NAME=sreez-website
TAG="${1}"
TAG="v1.8.2"
IMAGE="${REGISTRY}/${IMAGE_NAME}:${TAG}"
echo "Going to build and push image ${IMAGE}"
echo -n "Going to build and push image ${IMAGE}. [enter] to continue "
read
docker build -t "${IMAGE}" .
# docker push "${1}"
docker push "${IMAGE}"
echo -n "Image is built and pushed, do you want to commit and deploy this new version ? [enter] to continue, CTRL+C to abort "
read
python ../helm/tools/update_yaml.py ../helm/sreez-website/values.yaml .image.tag "${TAG}"

1
sreez/config.toml Normal file
View File

@@ -0,0 +1 @@
discord_webhook_url = "https://discord.com/api/webhooks/1230205994055762081/IUfZThaKpHCdlALdRr9orDBoJwlYepIKa2s8p_LvPk1hOBDYxpSyfBW98jGLLxGlOs2i"

View File

@@ -1,8 +1,13 @@
use leptos::*;
use leptos_meta::*;
use leptos_router::*;
use logging::log;
use chrono::Utc;
use crate::config::get_discord_webhook_url;
use crate::pages::ShortLandingPage;
use crate::pages::OkdInstallationOverview1;
use crate::pages::OkdRecoverFromExpiredCerts;
use crate::pages::HomePage;
use crate::pages::InitialOffer;
use crate::components::Matomo;
@@ -10,6 +15,7 @@ use crate::components::Matomo;
#[component]
pub fn App() -> impl IntoView {
// Provides context that manages stylesheets, titles, meta tags, etc.
log!("Got a hit {}", Utc::now());
provide_meta_context();
view! {
@@ -21,7 +27,6 @@ pub fn App() -> impl IntoView {
// sets the document title
<Title text="SREEZ - Site Reliability Engineering for Everyone, eZ"/>
// content for this welcome page
<Router>
<main class="bg-main bg-light">
@@ -29,6 +34,8 @@ pub fn App() -> impl IntoView {
<Route path="" view=ShortLandingPage/>
<Route path="/home-page" view=HomePage/>
<Route path="/initial-offer" view=InitialOffer/>
<Route path="/okd-installation-overview-1" view=OkdInstallationOverview1/>
<Route path="/okd-recover-from-expired-certs" view=OkdRecoverFromExpiredCerts/>
<Route path="/*any" view=NotFound/>
</Routes>
</main>

View File

@@ -1,7 +1,10 @@
use leptos::*;
#[component]
pub fn BookADemo() -> impl IntoView {
pub fn BookADemo(
#[prop(optional)]
text: String
) -> impl IntoView {
let (is_clicked, set_clicked) = create_signal(false);
view! {
@@ -10,7 +13,7 @@ pub fn BookADemo() -> impl IntoView {
on:click=move |_| {
set_clicked.update(|is_clicked| *is_clicked = !*is_clicked)
}
>"Book a demo →"</button>
>{text}</button>
<div class="animate-vertical sm-margin-top-2" data-visible=is_clicked>
<script src="https://embed.ycb.me" async="true" data-domain="jggc"></script>
</div>

View File

@@ -2,32 +2,36 @@ use leptos::*;
#[component]
pub fn Footer() -> impl IntoView {
let (is_clicked, set_clicked) = create_signal(false);
view! {
<div class="pad-y-4 margin-top-5 text-left max-width-900 margin-x-1 lg-margin-x-auto">
<p>"Reach us here :"</p>
<p>
<a href="linkedin" aria-label="NationTech LinkedIn page" aria-hidden="true" class="row items-center">
<a href="https://www.linkedin.com/company/83986494" aria-label="NationTech LinkedIn page" aria-hidden="true" target="_blank" class="row items-center">
<img src="assets/icons/linkedin.svg" height="32px"/>
<span class="pad-left-1">"LinkedIn"</span>
</a>
</p>
<p>
<a href="https://jggc.youcanbook.me" aria-label="You Can Book Me" aria-hidden="true" class="row items-center">
<a href="https://discord.gg/jKprrek8AF" aria-label="Discord" aria-hidden="true" target="_blank" class="row items-center">
<img src="assets/icons/discord_black.svg" width="32px"/>
<span class="pad-left-1">"Join our Discord community"</span>
</a>
</p>
<p>
<a href="https://jggc.youcanbook.me" aria-label="You Can Book Me" aria-hidden="true" target="_blank" class="row items-center">
<img src="assets/icons/youcanbookme_black.png" height="32px"/>
<span class="pad-left-1">"Book a meeting"</span>
</a>
</p>
<p>
<a href="https://nationtech.io" aria-label="NationTech website" aria-hidden="true" class="row items-center">
<a href="https://nationtech.io" aria-label="NationTech website" aria-hidden="true" target="_blank" class="row items-center">
<img src="assets/icons/website.svg" height="32px"/>
<span class="pad-left-1">"nationtech.io"</span>
</a>
</p>
<p>
<a href="mailto=sreez@nationtech.io" aria-label="SREEZ Email Address" aria-hidden="true" class="row items-center no-decoration">
<a href="mailto:sreez@nationtech.io" aria-label="SREEZ Email Address" aria-hidden="true" target="_blank" class="row items-center no-decoration">
<span class="icon-as-image material-symbols-outlined">"mail"
</span>
<span class="pad-left-1 underline">"sreez@nationtech.io"</span>

View File

@@ -1,6 +1,8 @@
mod book_a_demo;
mod footer;
mod matomo;
mod subscribe;
pub use subscribe::*;
pub use book_a_demo::*;
pub use footer::*;
pub use matomo::*;

View File

@@ -0,0 +1,55 @@
use leptos::*;
use leptos_router::use_location;
use leptos::logging::log;
#[cfg(feature = "ssr")]
use crate::infra::discord::send_discord_message;
use regex::Regex;
fn is_valid_email(email: &str) -> bool {
let regex = Regex::new(r"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$").unwrap();
return regex.is_match(email);
}
#[server(Subscribe, "/subscribe")]
pub async fn add_subscriber(message: String, email: String) -> Result<(), ServerFnError> {
let notification = &format!("New subscriber email : {} , message : {}", email, message);
log!("Sending new subscriber notification {} ", notification);
#[cfg(feature = "ssr")]
send_discord_message(notification).await?;
Ok(())
}
#[component]
pub fn SubscribeButton() -> impl IntoView {
let FORM_INITIAL = "INITIAL";
let FORM_SUCCESS ="SUCCESS";
let FORM_ERROR ="ERROR";
let (form_status, set_form_status) = create_signal(FORM_INITIAL);
let email : NodeRef<html::Input> = create_node_ref();
let send = move |ev: leptos::ev::SubmitEvent | {
ev.prevent_default();
let email_value = email.get().expect("Email input should be mounted").value();
spawn_local(async move {
if is_valid_email(&email_value) {
let path = use_location().pathname.get();
let _ = add_subscriber(path, email_value).await;
set_form_status(FORM_SUCCESS);
} else {
log!("Invalid email {}", email_value);
set_form_status(FORM_ERROR);
}
});
};
view! {
<form on:submit=send class="margin-y-3">
<label for="email" class="margin-right-1 margin-y-1">"Email : "</label>
<input type="text" placeholder="your@email.com" node_ref=email class="margin-right-3 input margin-y-1"/>
<input type="Submit" value="Subscribe" class="btn margin-y-1"/>
<p class=format!("form-message initial status-{}", form_status.get())><span>"Status is "</span><span>{form_status}</span></p>
</form>
}
}

28
sreez/src/config.rs Normal file
View File

@@ -0,0 +1,28 @@
use std::env;
use toml;
use std::fs;
use serde::Deserialize;
#[derive(Deserialize, Debug)]
struct Config {
discord_webhook_url: String,
}
fn get_full_config() -> Option<Config> {
if let Ok(config) = fs::read_to_string("config.toml") {
return toml::from_str(&config).unwrap_or(None);
}
None
}
pub fn get_discord_webhook_url() -> Option<String> {
if let Ok(url) = env::var("DISCORD_WEBHOOK_URL") {
return Some(url);
}
if let Some(config) = get_full_config() {
return Some(config.discord_webhook_url);
}
return None;
}

View File

@@ -0,0 +1,25 @@
use crate::config::get_discord_webhook_url;
#[cfg(feature = "ssr")]
use awc::{error::SendRequestError, Client};
#[cfg(feature = "ssr")]
use serde_json::json;
#[cfg(feature = "ssr")]
pub async fn send_discord_message(content: &str) -> Result<(), SendRequestError> {
let webhook_url = get_discord_webhook_url().expect("Webhook url configuration is available");
let client = Client::default();
let mut request = client.post(webhook_url);
request = request.insert_header(("User-Agent", "Actix-web"));
let body = json!({
"content": content,
});
let response = request.send_json(&body).await?;
println!("Response: {:?}", response);
Ok(())
}

1
sreez/src/infra/mod.rs Normal file
View File

@@ -0,0 +1 @@
pub mod discord;

View File

@@ -1,6 +1,8 @@
pub mod app;
mod pages;
mod components;
mod config;
mod infra;
#[cfg(feature = "hydrate")]
#[wasm_bindgen::prelude::wasm_bindgen]

View File

@@ -1,6 +1,10 @@
mod home_page;
mod initial_offer;
mod short_landing_page;
mod okd_installation_overview_1;
mod okd_recover_from_expired_certs;
pub use short_landing_page::*;
pub use home_page::*;
pub use initial_offer::*;
pub use okd_installation_overview_1::*;
pub use okd_recover_from_expired_certs::*;

View File

@@ -0,0 +1,140 @@
use leptos::*;
use leptos_meta::*;
use crate::components::{Footer, SubscribeButton};
/// Renders the home page of your application.
#[component]
pub fn OkdInstallationOverview1() -> impl IntoView {
provide_meta_context();
view! {
<Meta property="og:title" content="RedHat OKD - Survol d'une installation HA On-Prem"/>
<Meta property="og:image" content="https://sreez.nationtech.io/assets/okd-install-blog-part-1-thumbnail.png"/>
<Meta property="og:url" content="https://sreez.nationtech.io/okd-installation-overview-1"/>
<Meta property="og:description" content="Une vue haut niveau des requis et étapes nécessaires pour installer un cluster RedHat OKD hautement disponible sur bare metal."/>
<Meta property="og:author" content="Sylvain Tremblay"/>
<div class="margin-x-auto max-width-900">
// <div class="fixed-blog-header">
<div class="">
<div class="row margin-top-2 space-between">
<div class="margin-x-1 text-left column">
<h1 class="font-3xl">"RedHat OKD"
<span class="font-l font-italic">" -OpenShift Community Edition-"</span>
<br/>
<span class="font-2xl color-gray">"Survol d'une installation HA On-Prem."</span>
</h1>
</div>
<div class="flex-align-start pad-top-2 pad-right-1">
<img src="assets/Red_Hat_logo.png" alt="RedHat logo" class="height-70"/>
</div>
</div>
<div class="text-left margin-x-1 font-m">
"["<i>"Première partie"</i>"]"
</div>
</div>
<div class="margin-top-1">
// <div class="margin-x-1 text-justify column font-m blog-content">
<div class="margin-x-1 text-justify column font-m">
<p>"Dans cet article en plusieurs parties, je vous offre une vue à haut niveau des requis et étapes nécessaires pour installer un cluster "<b>"RedHat OKD"</b>" hautement disponible (3+ nodes) sur"<i>" bare metal"</i>". Dans la terminologie RedHat, on parle ici d'une installation de type"<b>" UPI"</b>" - "<i><b>"U"</b>"ser "<b>"P"</b>"rovisioned "<b>"I"</b>"nfrastructure"</i>"."</p>
<p>"Attention: ne vous attendez pas à un cookbook. Pas de longues listes de commandes, je ne prendrai personne par la main. Il s'agit plutôt d'un survol, un "<i>" preflight check "</i>" pour avoir une idée générale de la marche à suivre, des compétences requises, et être averti de pièges à éviter par lesquels je suis passé." </p>
<p>"Si vous comprenez ce que je raconte et avez les skills pour l'exécuter, vous êtes capables d'installer "<b>"OKD"</b>"." </p>
<h2 class="margin-top-5 color-okd-gray">"Mais avant de commencer... C'est quoi OKD?"</h2>
<div >
<p>
<img src="assets/OKD4.png" alt="OKD logo" class="max-width-400 margin-left-2 image-float-right"/>
"Dans le monde de kubernetes, OpenShift de RedHat, c'est plus que du bonbon. Ça ajoute des fonctionnalités et des outils supplémentaires à k8s qui facilitent énormément la vie et permettent de créer rapidement, avec surprenamment peu d'efforts, un environnement "<i>"production ready"</i>" hautement disponible incluant dès le départ du monitoring, de l'alerting, des mises-à-jour automatique, et bien plus. "</p>
</div>
<p>"C'est bien beau, on jase d'OpenShift, mais OKD, c'est quoi? C'est la version open source gratuite d'OpenShift. Le modèle d'affaire de RedHat repose sur la fourniture de solutions logicielles open source, le support technique et les services associés. Donc, en gros, si on engage RedHat pour installer/supporter/opérer un cluster, on a OpenShift. Si on s'arrange par soi-même, on a OKD."</p>
<h2 class="margin-top-5 color-okd-gray">"Connaissances requises"</h2>
<p>
"Afin de vous permettre d'évaluer rapidement si cette installation est à votre portée, voici une liste de technos qui vont être utlilisées pour monter le setup. Si tous ces buzzwords vous parlent, ou à tout le moins, ne vous effraient pas, vous avez les skills requis pour vous lancer dans l'installation."
// <div class="row">
<div class="row">
<ul class="columns-list">
<li>PXE</li>
<li>TFTP</li>
<li>DHCP</li>
<li>DNS</li>
<li>HTTPD</li>
<li>Firewall</li>
<li>Load Balancer</li>
<li>VPN</li>
<li>BIOS</li>
</ul>
// <img src="assets/okdPanda.jpeg" alt="RedHat logo" class="" style="max-height:100%; flex:1;"/>
//<p>yo</p>
</div>
"Cette liste n'est pas exhaustive, mais elle vient donner une idée de la trail dans laquelle on s'embarque / du profil que ça prend pour réussir cette installation."
</p>
<h2 class="margin-top-4 color-okd-gray">"Le setup visé"</h2>
<p>
"L'architecture logicielle finale de ce que l'on va construire ressemblera grossièrement à ceci:"
// <ul class="line-1-5">
<ul>
<li><p>"3 nodes de type "<i>"Control Plane"</i>" (qui seront aussi des "<i>"Workers"</i>")"</p></li>
<li><p>"1 node de type "<i>"Worker"</i></p></li>
<li><p>"Un serveur DHCP qui fournit IP et Hostname aux nodes du cluster selon leur MAC address"</p></li>
<li><p>"Un serveur DNS qui resolve les addresses du cluster pour les envoyer vers le load balancer"</p></li>
<li><p>"Un load balancer qui distribue les requêtes vers les 3 "<i>"control planes"</i></p></li>
<li><p>"Un serveur VPN pour accéder à l'infrastructure"</p></li>
</ul>
</p>
<h2 class="margin-top-3 color-okd-gray">"Le hardware requis"</h2>
<p>
"L'installation qui sera décrite dans la suite de cet article pourrait très bien se faire dans un setup complètement virtuel. Par contre, le but visé ici étant "<i>"bare metal"</i>", nous n'emprunterons pas cette voie. Voici donc la description du matériel physique requis:"
<ul>
<li><p>"Une switch et du câblage réseau"</p></li>
<li><p>"Une machine pour "<i>"OPNSense"</i>" (qui fournira les services: Firewall, DNS, DHCP, Load Balancer, VPN) [Pas besoin d'un monstre, capable de rouler sur un CPU 2 threads avec 2GB RAM]"</p></li>
<li><p>"Trois machines "<i>"Master / Control Plane"</i>" [Minimum 16GB RAM, 4 threads]"</p></li>
<li><p>"Une machine qui va servir de "<i>"bootstrap node"</i>" lors de l'installation et sera ensuite recyclée en "<i>"worker"</i>" [Minimum 16GB RAM, 4 threads, Idéalement bcp de RAM, bcp de threads]"</p></li>
<li><p>"Une machine pour le serveur PXE (TFTP + HTTP). Cette machine est nécessaire lors de l'installation initiale, et pour tout remplacement / ajout de node dans le cluster. [Pas besoin de beaucoup de puissance, j'utilise un "<i>"Raspberry Pi 4"</i>" avec 4GB RAM]"</p></li>
</ul>
</p>
<h2 class="margin-top-3 color-okd-gray">"La suite dans le prochain épisode..."</h2>
<p>
"Tout comme une bonne série télé, c'est au moment où l'on arrive dans l'action que la saison se termine. Maintenant que nous connaissons notre objectif et le matériel requis pour l'atteindre, nous allons être prêts à entrer dans le vif du sujet : l'installation. J'espère que cette première partie a su s'avérer intéressante et a éveillé un intérêt, la prochaine suivra sous peu!"
</p>
<h2 class="margin-top-5 color-okd-gray">"Références"</h2>
<ul>
<li><a href="https://www.okd.io/" target="_blank">"Site Web OKD"</a></li>
<li><a href="https://docs.okd.io/latest/installing/index.html" target="_blank">"Documentation officielle d'installation OKD"</a></li>
<li><a href="https://www.redhat.com/en/topics/containers/red-hat-openshift-okd" target="_blank">"Red Hat OpenShift vs. OKD [Par RedHat]"</a></li>
</ul>
</div>
<div class="margin-top-4">
<p>"Intéressé par la suite ?"</p>
<p>"Soyez notifié lors de la publication de la prochaine partie !"</p>
<SubscribeButton/>
</div>
<div class="margin-y-3 margin-x-1 font-m text-justify">
<p>"Article écrit par : "</p>
<p><strong>"Sylvain Tremblay"</strong></p>
<p>
<a class="row items-center no-decoration" href="https://www.linkedin.com/in/sylvain-tremblay-a881151/" target="_blank">
<img src="assets/icons/linkedin.svg" height="32px"/>
<span class="pad-left-1">"LinkedIn"</span>
</a>
</p>
<p>
<a class="row items-center no-decoration" href="https://www.linkedin.com/in/sylvain-tremblay-a881151/" target="_blank">
<span class="icon-as-image material-symbols-outlined">"mail"</span>
<span class="pad-left-1 underline">"stremblay@nationtech.io"</span>
</a>
</p>
<p class="margin-top-3">"Sylvain, co-fondateur et CTO de NationTech, a \"été choisi\" par l'informatique dès l'age de 9 ans. Passionné par tous les aspects du domaine, après quelques années de [gwbasic, turbo pascal, c, c++, asm] c'est particulièrement l'administration de systèmes et les infrastructures complexes qui ont captivé son intérêt. Nous sommes ici à l'époque des BBS, bien avant qu'internet soit disponible aux clients résidentiels."</p>
<p>"Il a été parmi les premiers utilisateurs de Linux dès 1992, a ensuite travaillé sur différents systèmes Unix commerciaux à l'occasion de ses années de travail chez Bombardier [Transports, Aerospace], Ferrari F1 ou Hyundai-Kia Motor Corporation. "</p>
<p>"Il est ensuite revenu dans le monde de l'informatique pure après un séjour en tant qu'informaticien au millieu d'ingénieurs mécaniques. C'est alors qu'il occupe le poste de programmeur pendant plusieurs années, puis d'architecte cloud, spécialiste en infrastructures distribuée, etc. En plus de son travail dans le domaine, il s'affaire dans ses passes temps à des expérimentations poussées avec les technologies de l'heure soit OpenStack dans les années 2010 puis Kubernetes dont il développe une maîtrise avancée."</p>
<p>"Effectivement, pour Sylvain toutes les raisons sont bonnes pour acheter un serveur à ajouter dans son homelab ou une imprimante 3D de plus et il les utilise à bon escient, toujours fidèle à sa grande générosité."</p>
</div>
</div>
</div>
<Footer />
}
}

File diff suppressed because one or more lines are too long

View File

@@ -1,22 +1,29 @@
use leptos::*;
use leptos_meta::*;
use crate::components::BookADemo;
use crate::components::Footer;
/// Renders the home page of your application.
#[component]
pub fn ShortLandingPage() -> impl IntoView {
provide_meta_context();
view! {
<Meta property="og:image" content="https://sreez.nationtech.io/assets/sreez_og_banner.png"/>
<Meta property="og:image:width" content="1200"/>
<Meta property="og:image:height" content="630"/>
<div class="margin-x-auto lg-margin-x-3">
<img src="assets/sreez_logo_shaded_v2.png" aria-label="SREEZ mascot of a cherry because SREEZ sounds like 'cerise' in French which means Cherry" class="max-width-150"/>
<img src="assets/sreez_logo_shaded_v2.png" aria-label="SREEZ mascot of a cherry because SREEZ sounds like 'cerise' in French which means Cherry" class="max-width-150 margin-top-5"/>
</div>
<div class="max-width-900 margin-x-auto">
<div class="margin-x-1 lg-margin-x-3 text-left">
<h1>"Accelerate your software delivery with SREEZ."</h1>
<p>"Focus on what really matters."</p>
<p>"Stop being overwhelmed by platform and infrastructure work."</p>
<p>"Get our platform deployed and your projects migrated faster than you thought possible."</p>
<div class="margin-top-2 text-center lg-text-left">
<BookADemo />
<h1 class="margin-y-4">"Accelerate your software delivery with SREEZ."</h1>
<p class="margin-y-2">"Focus on what really matters."</p>
<p class="margin-y-2">"Stop being overwhelmed by platform and deployment chores."</p>
<p class="margin-y-2">"Get our platform deployed and your projects migrated faster than you thought possible."</p>
<div class="margin-y-4 text-center lg-text-left">
<BookADemo text="Book a demo →".to_string() />
</div>
</div>
<div class="card max-width-600 margin-x-auto margin-y-4">
@@ -28,44 +35,7 @@ pub fn ShortLandingPage() -> impl IntoView {
<li>"An all-in-one software delivery platform with services you didn't think you could afford"</li>
</ul>
</div>
<h2 class="margin-top-5">"Struggling to keep your DevOps tools up to par ?"</h2>
<div class="lg-lr-sections">
<div class="card max-width-600 margin-x-auto margin-y-4">
<span class="material-symbols-outlined card-icon">"price_change"</span>
<p>"With an ever-growing DevOps toolchain, most teams cannot afford to invest the time and money required to build the pipeline they know they need."</p>
</div>
<div class="card max-width-600 margin-x-auto margin-y-4">
<span class="material-symbols-outlined card-icon">"stacks"</span>
<p>"We fix that by building a unified platform for small and medium teams."</p>
</div>
<div class="card max-width-600 margin-x-auto margin-y-4">
<span class="material-symbols-outlined card-icon">"waving_hand"</span>
<div>
<p>"Our platform engineering experts work with you to select the best fitting open-source tools such as"</p>
<ul class="text-left list-pad-1">
<li>"Kubernetes"</li>
<li>"RedHat Developer Hub"</li>
<li>"ArgoCD"</li>
<li>"Grafana"</li>
<li>"HyperDX"</li>
</ul>
<img src="assets/sreez_stack_logos_flat.png" alt="SREEZ stack logos" class="width-600 max-width-100pct margin-top-2" />
</div>
</div>
<div class="card max-width-600 margin-x-auto margin-y-4">
<span class="material-symbols-outlined card-icon">"engineering"</span>
<div>
<h3>"Wo do all this for you"</h3>
<ul class="text-left list-pad-1">
<li>"Migrate your existing applications to the platform"</li>
<li>"Coach your team on best practices"</li>
<li>"Be the 24/7 first respondants to incidents, only waking you up when it really matters"</li>
<li>"Continuously improve your delivery speed, quality and reliability"</li>
</ul>
</div>
</div>
</div>
<h2 class="margin-top-8">"Delivering faster means your business wins : join the Elite with our unique early adopter offer!"</h2>
<h2 class="margin-top-8">"Deploy in MINUTES, instead of WEEKS : join the Elite with our unique early adopter offer!"</h2>
<div class="card max-width-600 margin-x-auto margin-top-5">
<span class="material-symbols-outlined card-icon">"editor_choice"</span>
<h3 class="pad-y-1">"Get a pioneer seat to be a key part of the SREEZ project's foundation."</h3>
@@ -79,7 +49,62 @@ pub fn ShortLandingPage() -> impl IntoView {
</ul>
</div>
<div class="margin-top-5">
<BookADemo />
<BookADemo text="Book a demo →".to_string() />
</div>
<h2 class="margin-y-8">"Struggling to keep your DevOps tools up to par ?"</h2>
<div class="lg-lr-sections">
<div class="card max-width-600 margin-x-auto margin-y-8">
<span class="material-symbols-outlined card-icon">"price_change"</span>
<p>"With an ever-growing DevOps toolchain, most teams cannot afford to invest the time and money required to build the pipeline they know they need."</p>
</div>
<div class="card max-width-600 margin-x-auto margin-y-8">
<span class="material-symbols-outlined card-icon">"stacks"</span>
<p>"We fix that by building a unified platform for small and medium teams."</p>
</div>
<div class="card max-width-600 margin-x-auto margin-y-8">
<span class="material-symbols-outlined card-icon">"waving_hand"</span>
<div>
<p>"Our platform engineering experts work with you to select the best fitting open-source tools such as"</p>
<ul class="text-left list-pad-1">
<li>"Kubernetes"</li>
<li>"RedHat Developer Hub"</li>
<li>"ArgoCD"</li>
<li>"Grafana"</li>
<li>"HyperDX"</li>
</ul>
<img src="assets/sreez_stack_logos_flat.png" alt="SREEZ stack logos" class="width-600 max-width-100pct margin-top-2" />
</div>
</div>
<div class="card max-width-600 margin-x-auto margin-y-8">
<span class="material-symbols-outlined card-icon">"engineering"</span>
<div>
<h3>"Wo do all this for you"</h3>
<ul class="text-left list-pad-1">
<li>"Migrate your existing applications to the platform"</li>
<li>"Coach your team on best practices"</li>
<li>"Be the 24/7 first respondants to incidents, only waking you up when it really matters"</li>
<li>"Continuously improve your delivery speed, quality and reliability"</li>
</ul>
</div>
</div>
</div>
<h2 class="margin-y-8">"Get in touch to build the perfect package"</h2>
<div class="card max-width-600 margin-x-auto margin-top-5">
<span class="material-symbols-outlined card-icon">"redeem"</span>
<div>
<p>"Mix and match our services to create the ideal combination"</p>
<ul class="text-left list-pad-1">
<li>"Sustainable hosting"</li>
<li>"Internal Development Platform"</li>
<li>"CI/CD Automation"</li>
<li>"Hardware planning, ordering and installation"</li>
<li>"Process audits and coaching following DevOps principles"</li>
</ul>
</div>
</div>
<div class="margin-top-5">
<BookADemo text="Discuss the perfect package".to_string() />
</div>
</div>
<Footer/>

View File

@@ -1,3 +1,7 @@
@tailwind base;
@tailwind components;
@tailwind utilities;
@font-face {
font-family: "Fira Mono";
src:
@@ -25,6 +29,19 @@ body {
font-size: 1.4rem;
}
.fixed-blog-header {
position: fixed;
top: 0;
background-color: #f8f9f1;
width: -webkit-fill-available;
max-width: 900;
z-index: 999;
}
.blog-content {
padding-top: 180px;
}
.line-2-5 {
line-height: 2.5rem;
}
@@ -33,16 +50,74 @@ body {
font-size: 3rem;
}
.font-3xl {
font-size: 2.5rem;
}
.font-2xl {
font-size: 2rem;
}
.font-xl {
font-size: 1.7rem;
}
.font-l {
font-size: 1.5rem;
}
.font-m {
font-size: 1.2rem;
}
.font-s {
font-size: 1rem;
}
.font-italic {
font-style: italic;
}
.columns-list {
display: block;
column-count: 3;
column-gap: 1rem;
padding: 0;
margin-top: 2rem;
margin-bottom: 3rem;
margin-left: 6rem;
margin-right: 6rem;
list-style-position: inside;
white-space: nowrap;
}
.columns-list li {
display: list-item;
break-inside: avoid;
list-style-position: inside;
// padding: 0.5rem 0;
// margin-left: 20px;
margin-bottom: 0.5rem;
}
.line-1 {
line-height: 1rem;
}
.line-1-5 {
line-height: 1.5rem;
}
.line-2 {
line-height: 2rem;
}
.color-gray {
color: gray
color: gray;
}
.color-okd-gray {
color: #344559;
}
ol {
@@ -67,6 +142,13 @@ ol {
text-decoration: none;
}
.front-image {
// max-width: 900px;
min-width: 200px;
width: 100%;
height: auto;
}
.icon-as-image {
color: black;
text-decoration: none;
@@ -81,6 +163,10 @@ ol {
align-items: center;
}
.justify-end {
justify-content: end;
}
.justify-center {
justify-content: center;
}
@@ -90,11 +176,43 @@ ol {
margin-right: 1rem;
}
.margin-y-8 {
margin-top: 8rem;
margin-bottom: 8rem;
}
.margin-y-3 {
margin-top: 3rem;
margin-bottom: 3rem;
}
.margin-y-4 {
margin-top: 4rem;
margin-bottom: 4rem;
}
.margin-y-2 {
margin-top: 2rem;
margin-bottom: 2rem;
}
.margin-y-1 {
margin-top: 1rem;
margin-bottom: 1rem;
}
.pad-right-1 {
padding-right: 1rem;
}
.pad-right-2 {
padding-right: 2rem;
}
.pad-top-2 {
padding-top: 2rem;
}
.pad-y-4 {
padding-top: 4rem;
padding-bottom: 4rem;
@@ -118,6 +236,11 @@ ol {
margin-right: 3rem;
}
.margin-x-6 {
margin-left: 6rem;
margin-right: 6rem;
}
.margin-y-25vh {
margin-top: 25vh;
margin-bottom: 25vh;
@@ -127,6 +250,13 @@ ol {
margin: 3rem;
}
.margin-right-1 {
margin-right: 1rem;
}
.margin-right-3 {
margin-right: 3rem;
}
.max-width-300 {
max-width: 300px;
@@ -177,6 +307,10 @@ ol {
margin-top: 5rem;
}
.margin-top-4 {
margin-top: 4rem;
}
.margin-top-2 {
margin-top: 2rem;
}
@@ -185,6 +319,18 @@ ol {
margin-top: 1rem;
}
.margin-right-1 {
margin-right: 1rem;
}
.margin-right-2 {
margin-right: 2rem;
}
.margin-left-2 {
margin-left: 2rem;
}
.card {
.card-icon {
font-size: 7rem;
@@ -192,6 +338,11 @@ ol {
}
}
.image-float-right {
height: auto;
float: right;
}
.card-list {
text-align: left;
justify-content: center;
@@ -239,6 +390,14 @@ ol {
margin: auto;
}
.space-between {
justify-content: space-between;
}
.text-justify {
text-align: justify;
}
.text-left {
text-align: left;
}
@@ -282,10 +441,24 @@ ol.huge-list-markers li{
font-weight: 600;
}
.height-70 {
height: 70px;
}
.height-110 {
height: 110px;
}
.flex-align-start {
display: flex;
align-items: start;
}
.flex-align-center {
display: flex;
align-items: center;
}
.bg-light, body {
background-color: #F8F9F1;
}
@@ -302,14 +475,25 @@ ol.huge-list-markers li{
font-weight: 700;
font-size: inherit;
cursor: pointer;
background-color: #e72235;
color: white;
background-color: #e72235;
color: white;
&:hover {
// background-color: #eee;
// color: black;
box-shadow: 5px 5px 27px 10px rgba(231,34,53,0.21);
//background-color: #66d500;
//background-color: white;
box-shadow: 5px 5px 17px 5px rgba(231,34,53,0.21);
}
}
.input {
border: solid 2px #eee;
padding: 1rem 1.5rem;
border-radius: 0.75rem;
font-weight: 400;
font-size: inherit;
cursor: pointer;
background-color: white;
color: black;
&:focus {
box-shadow: 5px 5px 17px -5px rgba(0,0,0,0.21);
outline: none;
}
}
@@ -333,10 +517,106 @@ ol.huge-list-markers li{
max-height: 900px;
}
.code-block {
background-color: #2d2d2d; // Dark background color
color: #f8f8f2; // Light text color
padding: 1rem; // Padding around the code block
margin: 4rem 2.5rem;
border-radius: 0.5rem; // Rounded corners
overflow-x: auto; // Horizontal scroll for long lines
font-family: 'Courier New', Courier, monospace; // Monospace font
font-size: 1rem;
}
.code-block .token.comment,
.code-block .token.prolog,
.code-block .token.doctype,
.code-block .token.cdata {
color: #75715e; // Color for comments
}
.code-block .token.punctuation {
color: #f8f8f2; // Color for punctuation
}
.code-block .token.namespace {
opacity: .7; // Reduced opacity for namespaces
}
.code-block .token.property,
.code-block .token.tag,
.code-block .token.constant,
.code-block .token.symbol,
.code-block .token.deleted {
color: #f92672; // Color for properties, tags, etc.
}
.code-block .token.boolean,
.code-block .token.number {
color: #ae81ff; // Color for booleans and numbers
}
.code-block .token.selector,
.code-block .token.attr-name,
.code-block .token.string,
.code-block .token.char,
.code-block .token.builtin,
.code-block .token.inserted {
color: #a6e22e; // Color for selectors, attributes, etc.
}
.code-block .token.operator,
.code-block .token.entity,
.code-block .token.url,
.code-block .language-css .token.string,
.code-block .style .token.string,
.code-block .token.variable {
color: #f8f8f2; // Color for operators, entities, URLs, etc.
}
.code-block .token.atrule,
.code-block .token.attr-value,
.code-block .token.function,
.code-block .token.class-name {
color: #e6db74; // Color for at-rules, attribute values, etc.
}
.code-block .token.keyword {
color: #66d9ef; // Color for keywords
}
.code-block .token.regex,
.code-block .token.important {
color: #fd971f; // Color for regex and important
}
.code-block .token.important,
.code-block .token.bold {
font-weight: bold; // Bold font weight for important and bold
}
.code-block .token.italic {
font-style: italic; // Italic font style
}
.code-block .token.entity {
cursor: help; // Cursor style for entities
}
@media screen and (max-width: 768px) {
.sm-margin-top-2 {
margin-top: 2rem;
}
.columns-list {
column-count: 2;
margin-left: 4rem;
}
}
.form-message {
display: none;
// TODO handle dynamic class
}
@@ -355,6 +635,11 @@ ol.huge-list-markers li{
margin-right: 3rem;
}
.margin-x-6 {
margin-left: 6rem;
margin-right: 6rem;
}
.lg-lr-sections {
> div {
margin-right: 0;