chore: pc change
This commit is contained in:
1 parent
21ba5e45ff
commit
f7ca1ecbc5
27 files changed
+926
-262
No files matched your search
Generated
+436
-18
@@ -26,6 +26,21 @@ dependencies = [
|
|||||||
"memchr",
|
"memchr",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[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]]
|
[[package]]
|
||||||
name = "any_spawner"
|
name = "any_spawner"
|
||||||
version = "0.3.0"
|
version = "0.3.0"
|
||||||
@@ -565,7 +580,7 @@ dependencies = [
|
|||||||
"miniz_oxide",
|
"miniz_oxide",
|
||||||
"object",
|
"object",
|
||||||
"rustc-demangle",
|
"rustc-demangle",
|
||||||
"windows-targets",
|
"windows-targets 0.52.6",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -688,6 +703,21 @@ version = "1.0.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "chrono"
|
||||||
|
version = "0.4.41"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c469d952047f47f91b68d1cba3f10d63c11d73e4636f24f08daf0278abf01c4d"
|
||||||
|
dependencies = [
|
||||||
|
"android-tzdata",
|
||||||
|
"iana-time-zone",
|
||||||
|
"js-sys",
|
||||||
|
"num-traits",
|
||||||
|
"serde",
|
||||||
|
"wasm-bindgen",
|
||||||
|
"windows-link",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "clang-sys"
|
name = "clang-sys"
|
||||||
version = "1.8.1"
|
version = "1.8.1"
|
||||||
@@ -858,6 +888,41 @@ dependencies = [
|
|||||||
"typenum",
|
"typenum",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "darling"
|
||||||
|
version = "0.20.11"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "fc7f46116c46ff9ab3eb1597a45688b6715c6e628b5c133e288e709a29bcb4ee"
|
||||||
|
dependencies = [
|
||||||
|
"darling_core",
|
||||||
|
"darling_macro",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "darling_core"
|
||||||
|
version = "0.20.11"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0d00b9596d185e565c2207a0b01f8bd1a135483d02d9b7b0a54b11da8d53412e"
|
||||||
|
dependencies = [
|
||||||
|
"fnv",
|
||||||
|
"ident_case",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"strsim",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "darling_macro"
|
||||||
|
version = "0.20.11"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead"
|
||||||
|
dependencies = [
|
||||||
|
"darling_core",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "dashmap"
|
name = "dashmap"
|
||||||
version = "6.1.0"
|
version = "6.1.0"
|
||||||
@@ -878,6 +943,18 @@ version = "2.9.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2a2330da5de22e8a3cb63252ce2abb30116bf5265e89c0e01bc17015ce30a476"
|
checksum = "2a2330da5de22e8a3cb63252ce2abb30116bf5265e89c0e01bc17015ce30a476"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "default-struct-builder"
|
||||||
|
version = "0.5.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e0df63c21a4383f94bd5388564829423f35c316aed85dc4f8427aded372c7c0d"
|
||||||
|
dependencies = [
|
||||||
|
"darling",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "deranged"
|
name = "deranged"
|
||||||
version = "0.4.0"
|
version = "0.4.0"
|
||||||
@@ -1134,8 +1211,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592"
|
checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
|
"js-sys",
|
||||||
"libc",
|
"libc",
|
||||||
"wasi 0.11.0+wasi-snapshot-preview1",
|
"wasi 0.11.0+wasi-snapshot-preview1",
|
||||||
|
"wasm-bindgen",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -1482,6 +1561,30 @@ dependencies = [
|
|||||||
"tracing",
|
"tracing",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "iana-time-zone"
|
||||||
|
version = "0.1.63"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b0c919e5debc312ad217002b8048a17b7d83f80703865bbfcfebb0458b0b27d8"
|
||||||
|
dependencies = [
|
||||||
|
"android_system_properties",
|
||||||
|
"core-foundation-sys",
|
||||||
|
"iana-time-zone-haiku",
|
||||||
|
"js-sys",
|
||||||
|
"log",
|
||||||
|
"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]]
|
[[package]]
|
||||||
name = "icu_collections"
|
name = "icu_collections"
|
||||||
version = "1.5.0"
|
version = "1.5.0"
|
||||||
@@ -1600,6 +1703,12 @@ dependencies = [
|
|||||||
"syn",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ident_case"
|
||||||
|
version = "1.0.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "idna"
|
name = "idna"
|
||||||
version = "1.0.3"
|
version = "1.0.3"
|
||||||
@@ -1657,6 +1766,12 @@ dependencies = [
|
|||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ipnet"
|
||||||
|
version = "2.11.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "itertools"
|
name = "itertools"
|
||||||
version = "0.10.5"
|
version = "0.10.5"
|
||||||
@@ -1701,6 +1816,19 @@ dependencies = [
|
|||||||
"wasm-bindgen",
|
"wasm-bindgen",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "jsonwebtoken"
|
||||||
|
version = "9.3.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5a87cc7a48537badeae96744432de36f4be2b4a34a05a5ef32e9dd8a1c169dde"
|
||||||
|
dependencies = [
|
||||||
|
"base64 0.22.1",
|
||||||
|
"js-sys",
|
||||||
|
"ring",
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lazy_static"
|
name = "lazy_static"
|
||||||
version = "1.5.0"
|
version = "1.5.0"
|
||||||
@@ -1734,7 +1862,7 @@ dependencies = [
|
|||||||
"oco_ref",
|
"oco_ref",
|
||||||
"or_poisoned",
|
"or_poisoned",
|
||||||
"paste",
|
"paste",
|
||||||
"rand",
|
"rand 0.9.2",
|
||||||
"reactive_graph",
|
"reactive_graph",
|
||||||
"rustc-hash 2.1.1",
|
"rustc-hash 2.1.1",
|
||||||
"rustc_version",
|
"rustc_version",
|
||||||
@@ -1755,6 +1883,26 @@ dependencies = [
|
|||||||
"web-sys",
|
"web-sys",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "leptos-use"
|
||||||
|
version = "0.16.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c6eac17e7d306b4ad67158aba97c1490884ba304add4321069cb63fe0834c3b1"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"codee",
|
||||||
|
"default-struct-builder",
|
||||||
|
"js-sys",
|
||||||
|
"lazy_static",
|
||||||
|
"leptos",
|
||||||
|
"paste",
|
||||||
|
"send_wrapper",
|
||||||
|
"thiserror 2.0.12",
|
||||||
|
"wasm-bindgen",
|
||||||
|
"wasm-bindgen-futures",
|
||||||
|
"web-sys",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "leptos_axum"
|
name = "leptos_axum"
|
||||||
version = "0.8.5"
|
version = "0.8.5"
|
||||||
@@ -1878,6 +2026,26 @@ dependencies = [
|
|||||||
"web-sys",
|
"web-sys",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "leptos_oidc"
|
||||||
|
version = "0.9.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7797ff727c5b0b558faabe2bd784159b411803f56e384578d68471c699b85649"
|
||||||
|
dependencies = [
|
||||||
|
"chrono",
|
||||||
|
"codee",
|
||||||
|
"jsonwebtoken",
|
||||||
|
"leptos",
|
||||||
|
"leptos-use",
|
||||||
|
"leptos_router",
|
||||||
|
"oauth2",
|
||||||
|
"reqwest",
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
|
"thiserror 2.0.12",
|
||||||
|
"tracing",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "leptos_router"
|
name = "leptos_router"
|
||||||
version = "0.8.5"
|
version = "0.8.5"
|
||||||
@@ -1948,7 +2116,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "6a793df0d7afeac54f95b471d3af7f0d4fb975699f972341a4b76988d49cdf0c"
|
checksum = "6a793df0d7afeac54f95b471d3af7f0d4fb975699f972341a4b76988d49cdf0c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"windows-targets",
|
"windows-targets 0.53.3",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -1985,6 +2153,14 @@ version = "0.4.27"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94"
|
checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "macros"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "manyhow"
|
name = "manyhow"
|
||||||
version = "0.11.4"
|
version = "0.11.4"
|
||||||
@@ -2129,6 +2305,25 @@ dependencies = [
|
|||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "oauth2"
|
||||||
|
version = "5.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "51e219e79014df21a225b1860a479e2dcd7cbd9130f4defd4bd0e191ea31d67d"
|
||||||
|
dependencies = [
|
||||||
|
"base64 0.22.1",
|
||||||
|
"chrono",
|
||||||
|
"getrandom 0.2.16",
|
||||||
|
"http 1.3.1",
|
||||||
|
"rand 0.8.5",
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
|
"serde_path_to_error",
|
||||||
|
"sha2",
|
||||||
|
"thiserror 1.0.69",
|
||||||
|
"url",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "object"
|
name = "object"
|
||||||
version = "0.36.7"
|
version = "0.36.7"
|
||||||
@@ -2198,7 +2393,7 @@ dependencies = [
|
|||||||
"libc",
|
"libc",
|
||||||
"redox_syscall",
|
"redox_syscall",
|
||||||
"smallvec",
|
"smallvec",
|
||||||
"windows-targets",
|
"windows-targets 0.52.6",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -2368,14 +2563,35 @@ version = "5.2.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "74765f6d916ee2faa39bc8e68e4f3ed8949b48cccdac59983d287a7cb71ce9c5"
|
checksum = "74765f6d916ee2faa39bc8e68e4f3ed8949b48cccdac59983d287a7cb71ce9c5"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rand"
|
||||||
|
version = "0.8.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
"rand_chacha 0.3.1",
|
||||||
|
"rand_core 0.6.4",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rand"
|
name = "rand"
|
||||||
version = "0.9.2"
|
version = "0.9.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1"
|
checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"rand_chacha",
|
"rand_chacha 0.9.0",
|
||||||
"rand_core",
|
"rand_core 0.9.3",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rand_chacha"
|
||||||
|
version = "0.3.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
|
||||||
|
dependencies = [
|
||||||
|
"ppv-lite86",
|
||||||
|
"rand_core 0.6.4",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -2385,7 +2601,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb"
|
checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ppv-lite86",
|
"ppv-lite86",
|
||||||
"rand_core",
|
"rand_core 0.9.3",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rand_core"
|
||||||
|
version = "0.6.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
|
||||||
|
dependencies = [
|
||||||
|
"getrandom 0.2.16",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -2493,6 +2718,42 @@ version = "0.8.5"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c"
|
checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "reqwest"
|
||||||
|
version = "0.12.15"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d19c46a6fdd48bc4dab94b6103fccc55d34c67cc0ad04653aad4ea2a07cd7bbb"
|
||||||
|
dependencies = [
|
||||||
|
"base64 0.22.1",
|
||||||
|
"bytes",
|
||||||
|
"futures-core",
|
||||||
|
"futures-util",
|
||||||
|
"http 1.3.1",
|
||||||
|
"http-body 1.0.1",
|
||||||
|
"http-body-util",
|
||||||
|
"hyper 1.6.0",
|
||||||
|
"hyper-util",
|
||||||
|
"ipnet",
|
||||||
|
"js-sys",
|
||||||
|
"log",
|
||||||
|
"mime",
|
||||||
|
"once_cell",
|
||||||
|
"percent-encoding",
|
||||||
|
"pin-project-lite",
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
|
"serde_urlencoded",
|
||||||
|
"sync_wrapper",
|
||||||
|
"tokio",
|
||||||
|
"tower",
|
||||||
|
"tower-service",
|
||||||
|
"url",
|
||||||
|
"wasm-bindgen",
|
||||||
|
"wasm-bindgen-futures",
|
||||||
|
"web-sys",
|
||||||
|
"windows-registry",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ring"
|
name = "ring"
|
||||||
version = "0.17.14"
|
version = "0.17.14"
|
||||||
@@ -2693,9 +2954,12 @@ dependencies = [
|
|||||||
"leptos",
|
"leptos",
|
||||||
"leptos_axum",
|
"leptos_axum",
|
||||||
"leptos_meta",
|
"leptos_meta",
|
||||||
|
"leptos_oidc",
|
||||||
"leptos_router",
|
"leptos_router",
|
||||||
|
"macros",
|
||||||
"serde",
|
"serde",
|
||||||
"tokio",
|
"tokio",
|
||||||
|
"url",
|
||||||
"uuid",
|
"uuid",
|
||||||
"wasm-bindgen",
|
"wasm-bindgen",
|
||||||
]
|
]
|
||||||
@@ -2999,6 +3263,12 @@ version = "1.2.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3"
|
checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "strsim"
|
||||||
|
version = "0.11.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "subtle"
|
name = "subtle"
|
||||||
version = "2.6.1"
|
version = "2.6.1"
|
||||||
@@ -3033,6 +3303,9 @@ name = "sync_wrapper"
|
|||||||
version = "1.0.2"
|
version = "1.0.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263"
|
checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263"
|
||||||
|
dependencies = [
|
||||||
|
"futures-core",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "synstructure"
|
name = "synstructure"
|
||||||
@@ -3377,7 +3650,7 @@ dependencies = [
|
|||||||
"http 1.3.1",
|
"http 1.3.1",
|
||||||
"httparse",
|
"httparse",
|
||||||
"log",
|
"log",
|
||||||
"rand",
|
"rand 0.9.2",
|
||||||
"sha1",
|
"sha1",
|
||||||
"thiserror 2.0.12",
|
"thiserror 2.0.12",
|
||||||
"utf-8",
|
"utf-8",
|
||||||
@@ -3448,6 +3721,7 @@ dependencies = [
|
|||||||
"form_urlencoded",
|
"form_urlencoded",
|
||||||
"idna",
|
"idna",
|
||||||
"percent-encoding",
|
"percent-encoding",
|
||||||
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -3678,13 +3952,92 @@ dependencies = [
|
|||||||
"windows-sys 0.59.0",
|
"windows-sys 0.59.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-core"
|
||||||
|
version = "0.61.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c0fdd3ddb90610c7638aa2b3a3ab2904fb9e5cdbecc643ddb3647212781c4ae3"
|
||||||
|
dependencies = [
|
||||||
|
"windows-implement",
|
||||||
|
"windows-interface",
|
||||||
|
"windows-link",
|
||||||
|
"windows-result",
|
||||||
|
"windows-strings 0.4.2",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-implement"
|
||||||
|
version = "0.60.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a47fddd13af08290e67f4acabf4b459f647552718f683a7b415d290ac744a836"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-interface"
|
||||||
|
version = "0.59.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bd9211b69f8dcdfa817bfd14bf1c97c9188afa36f4750130fcdf3f400eca9fa8"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-link"
|
||||||
|
version = "0.1.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-registry"
|
||||||
|
version = "0.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4286ad90ddb45071efd1a66dfa43eb02dd0dfbae1545ad6cc3c51cf34d7e8ba3"
|
||||||
|
dependencies = [
|
||||||
|
"windows-result",
|
||||||
|
"windows-strings 0.3.1",
|
||||||
|
"windows-targets 0.53.3",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-result"
|
||||||
|
version = "0.3.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "56f42bd332cc6c8eac5af113fc0c1fd6a8fd2aa08a0119358686e5160d0586c6"
|
||||||
|
dependencies = [
|
||||||
|
"windows-link",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-strings"
|
||||||
|
version = "0.3.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "87fa48cc5d406560701792be122a10132491cff9d0aeb23583cc2dcafc847319"
|
||||||
|
dependencies = [
|
||||||
|
"windows-link",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-strings"
|
||||||
|
version = "0.4.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "56e6c93f3a0c3b36176cb1327a4958a0353d5d166c2a35cb268ace15e91d3b57"
|
||||||
|
dependencies = [
|
||||||
|
"windows-link",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows-sys"
|
name = "windows-sys"
|
||||||
version = "0.52.0"
|
version = "0.52.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
|
checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"windows-targets",
|
"windows-targets 0.52.6",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -3693,7 +4046,7 @@ version = "0.59.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b"
|
checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"windows-targets",
|
"windows-targets 0.52.6",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -3702,14 +4055,31 @@ version = "0.52.6"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
|
checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"windows_aarch64_gnullvm",
|
"windows_aarch64_gnullvm 0.52.6",
|
||||||
"windows_aarch64_msvc",
|
"windows_aarch64_msvc 0.52.6",
|
||||||
"windows_i686_gnu",
|
"windows_i686_gnu 0.52.6",
|
||||||
"windows_i686_gnullvm",
|
"windows_i686_gnullvm 0.52.6",
|
||||||
"windows_i686_msvc",
|
"windows_i686_msvc 0.52.6",
|
||||||
"windows_x86_64_gnu",
|
"windows_x86_64_gnu 0.52.6",
|
||||||
"windows_x86_64_gnullvm",
|
"windows_x86_64_gnullvm 0.52.6",
|
||||||
"windows_x86_64_msvc",
|
"windows_x86_64_msvc 0.52.6",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows-targets"
|
||||||
|
version = "0.53.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d5fe6031c4041849d7c496a8ded650796e7b6ecc19df1a431c1a363342e5dc91"
|
||||||
|
dependencies = [
|
||||||
|
"windows-link",
|
||||||
|
"windows_aarch64_gnullvm 0.53.0",
|
||||||
|
"windows_aarch64_msvc 0.53.0",
|
||||||
|
"windows_i686_gnu 0.53.0",
|
||||||
|
"windows_i686_gnullvm 0.53.0",
|
||||||
|
"windows_i686_msvc 0.53.0",
|
||||||
|
"windows_x86_64_gnu 0.53.0",
|
||||||
|
"windows_x86_64_gnullvm 0.53.0",
|
||||||
|
"windows_x86_64_msvc 0.53.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -3718,48 +4088,96 @@ version = "0.52.6"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
|
checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_aarch64_gnullvm"
|
||||||
|
version = "0.53.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_aarch64_msvc"
|
name = "windows_aarch64_msvc"
|
||||||
version = "0.52.6"
|
version = "0.52.6"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
|
checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_aarch64_msvc"
|
||||||
|
version = "0.53.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_i686_gnu"
|
name = "windows_i686_gnu"
|
||||||
version = "0.52.6"
|
version = "0.52.6"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
|
checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_i686_gnu"
|
||||||
|
version = "0.53.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c1dc67659d35f387f5f6c479dc4e28f1d4bb90ddd1a5d3da2e5d97b42d6272c3"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_i686_gnullvm"
|
name = "windows_i686_gnullvm"
|
||||||
version = "0.52.6"
|
version = "0.52.6"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
|
checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_i686_gnullvm"
|
||||||
|
version = "0.53.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_i686_msvc"
|
name = "windows_i686_msvc"
|
||||||
version = "0.52.6"
|
version = "0.52.6"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
|
checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_i686_msvc"
|
||||||
|
version = "0.53.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_x86_64_gnu"
|
name = "windows_x86_64_gnu"
|
||||||
version = "0.52.6"
|
version = "0.52.6"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
|
checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_x86_64_gnu"
|
||||||
|
version = "0.53.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_x86_64_gnullvm"
|
name = "windows_x86_64_gnullvm"
|
||||||
version = "0.52.6"
|
version = "0.52.6"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
|
checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_x86_64_gnullvm"
|
||||||
|
version = "0.53.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "windows_x86_64_msvc"
|
name = "windows_x86_64_msvc"
|
||||||
version = "0.52.6"
|
version = "0.52.6"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
|
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "windows_x86_64_msvc"
|
||||||
|
version = "0.53.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "winnow"
|
name = "winnow"
|
||||||
version = "0.7.12"
|
version = "0.7.12"
|
||||||
|
|||||||
@@ -19,6 +19,10 @@ aws-sdk-dynamodb = { version = "1.74.0", optional = true }
|
|||||||
aws-config = { version = "1.6.2", optional = true }
|
aws-config = { version = "1.6.2", optional = true }
|
||||||
serde = "1.0.219"
|
serde = "1.0.219"
|
||||||
uuid = { version = "1.17.0", features = ["serde", "v4", "js"] }
|
uuid = { version = "1.17.0", features = ["serde", "v4", "js"] }
|
||||||
|
leptos_oidc = "0.9.0"
|
||||||
|
url = "2.5.4"
|
||||||
|
|
||||||
|
macros = { path = "./macros" }
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
hydrate = [
|
hydrate = [
|
||||||
|
|||||||
@@ -1,91 +1,21 @@
|
|||||||
<picture>
|
# Region 15 Scholarship Application (Rust Rewrite)
|
||||||
<source srcset="https://raw.githubusercontent.com/leptos-rs/leptos/main/docs/logos/Leptos_logo_Solid_White.svg" media="(prefers-color-scheme: dark)">
|
|
||||||
<img src="https://raw.githubusercontent.com/leptos-rs/leptos/main/docs/logos/Leptos_logo_RGB.svg" alt="Leptos Logo">
|
|
||||||
</picture>
|
|
||||||
|
|
||||||
# Leptos Axum Starter Template
|
## Requirements
|
||||||
|
This repo requires that you have `cargo`, `clang`, and `node` installed.
|
||||||
|
|
||||||
This is a template for use with the [Leptos](https://github.com/leptos-rs/leptos) web framework and the [cargo-leptos](https://github.com/akesson/cargo-leptos) tool using [Axum](https://github.com/tokio-rs/axum).
|
- `cargo`: the project is written in Rust.
|
||||||
|
- `clang`: `ring`, a dependency of the `leptos_oidc` crate, requires this for compilation.
|
||||||
|
- `node`: required for `tailwindcss` compilation.
|
||||||
|
|
||||||
## Creating your template repo
|
## How to run
|
||||||
|
Run the command `cargo leptos watch` to compile and run an instance of the server on your local machine. To access info
|
||||||
|
from the AWS resources, you will need to be approved by me or someone else with AWS administrator access to obtain a
|
||||||
|
usable auth key from AWS IAM.
|
||||||
|
|
||||||
If you don't have `cargo-leptos` installed you can install it with
|
## Current Tasks
|
||||||
|
There are several tasks left to complete. These are a few of the larger ones:
|
||||||
|
|
||||||
```bash
|
- Build the application's custom elements
|
||||||
cargo install cargo-leptos --locked
|
- Build out the database requests
|
||||||
```
|
- Create proper authentication
|
||||||
|
- PDF generation using data (server-side)
|
||||||
Then run
|
|
||||||
```bash
|
|
||||||
cargo leptos new --git https://github.com/leptos-rs/start-axum
|
|
||||||
```
|
|
||||||
|
|
||||||
to generate a new project template.
|
|
||||||
|
|
||||||
```bash
|
|
||||||
cd scholarships-rs
|
|
||||||
```
|
|
||||||
|
|
||||||
to go to your newly created project.
|
|
||||||
Feel free to explore the project structure, but the best place to start with your application code is in `src/app.rs`.
|
|
||||||
Addtionally, Cargo.toml may need updating as new versions of the dependencies are released, especially if things are not working after a `cargo update`.
|
|
||||||
|
|
||||||
## Running your project
|
|
||||||
|
|
||||||
```bash
|
|
||||||
cargo leptos watch
|
|
||||||
```
|
|
||||||
|
|
||||||
## Installing Additional Tools
|
|
||||||
|
|
||||||
By default, `cargo-leptos` uses `nightly` Rust, `cargo-generate`, and `sass`. If you run into any trouble, you may need to install one or more of these tools.
|
|
||||||
|
|
||||||
1. `rustup toolchain install nightly --allow-downgrade` - make sure you have Rust nightly
|
|
||||||
2. `rustup target add wasm32-unknown-unknown` - add the ability to compile Rust to WebAssembly
|
|
||||||
3. `cargo install cargo-generate` - install `cargo-generate` binary (should be installed automatically in future)
|
|
||||||
4. `npm install -g sass` - install `dart-sass` (should be optional in future
|
|
||||||
5. Run `npm install` in end2end subdirectory before test
|
|
||||||
|
|
||||||
## Compiling for Release
|
|
||||||
```bash
|
|
||||||
cargo leptos build --release
|
|
||||||
```
|
|
||||||
|
|
||||||
Will generate your server binary in target/server/release and your site package in target/site
|
|
||||||
|
|
||||||
## Testing Your Project
|
|
||||||
```bash
|
|
||||||
cargo leptos end-to-end
|
|
||||||
```
|
|
||||||
|
|
||||||
```bash
|
|
||||||
cargo leptos end-to-end --release
|
|
||||||
```
|
|
||||||
|
|
||||||
Cargo-leptos uses Playwright as the end-to-end test tool.
|
|
||||||
Tests are located in end2end/tests directory.
|
|
||||||
|
|
||||||
## Executing a Server on a Remote Machine Without the Toolchain
|
|
||||||
After running a `cargo leptos build --release` the minimum files needed are:
|
|
||||||
|
|
||||||
1. The server binary located in `target/server/release`
|
|
||||||
2. The `site` directory and all files within located in `target/site`
|
|
||||||
|
|
||||||
Copy these files to your remote server. The directory structure should be:
|
|
||||||
```text
|
|
||||||
scholarships-rs
|
|
||||||
site/
|
|
||||||
```
|
|
||||||
Set the following environment variables (updating for your project as needed):
|
|
||||||
```sh
|
|
||||||
export LEPTOS_OUTPUT_NAME="scholarships-rs"
|
|
||||||
export LEPTOS_SITE_ROOT="site"
|
|
||||||
export LEPTOS_SITE_PKG_DIR="pkg"
|
|
||||||
export LEPTOS_SITE_ADDR="127.0.0.1:3000"
|
|
||||||
export LEPTOS_RELOAD_PORT="3001"
|
|
||||||
```
|
|
||||||
Finally, run the server binary.
|
|
||||||
|
|
||||||
## Licensing
|
|
||||||
|
|
||||||
This template itself is released under the Unlicense. You should replace the LICENSE for your own application with an appropriate license if you plan to release it publicly.
|
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
[package]
|
||||||
|
name = "macros"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2024"
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
proc-macro = true
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
syn = "2.0"
|
||||||
|
quote = "1.0"
|
||||||
@@ -0,0 +1,78 @@
|
|||||||
|
use proc_macro::TokenStream;
|
||||||
|
use quote::quote;
|
||||||
|
use syn::{Data, Ident, parse_macro_input};
|
||||||
|
|
||||||
|
#[proc_macro_derive(Reactive)]
|
||||||
|
pub fn make_reactive(input: TokenStream) -> TokenStream {
|
||||||
|
let input = parse_macro_input!(input as syn::DeriveInput);
|
||||||
|
|
||||||
|
let name = input.ident;
|
||||||
|
let reactive_name = Ident::new(&format!("{}Reactive", name), name.span());
|
||||||
|
|
||||||
|
let fields = if let Data::Struct(data) = input.data {
|
||||||
|
data.fields
|
||||||
|
} else {
|
||||||
|
panic!("Only structs can be reactive")
|
||||||
|
};
|
||||||
|
|
||||||
|
// Build the new fields.
|
||||||
|
let mut new_fields = Vec::new();
|
||||||
|
let mut new_fn_args = Vec::new();
|
||||||
|
let mut from_fn_args = Vec::new();
|
||||||
|
|
||||||
|
for field in fields {
|
||||||
|
let field_name = field.ident.unwrap();
|
||||||
|
let field_type = field.ty;
|
||||||
|
|
||||||
|
let new_field = quote! {
|
||||||
|
pub #field_name: _RwSignal<#field_type>,
|
||||||
|
};
|
||||||
|
|
||||||
|
new_fields.push(new_field);
|
||||||
|
|
||||||
|
// Create new function arguments/inits
|
||||||
|
let new_fn_arg = quote! {
|
||||||
|
#field_name: _RwSignal::new(data.#field_name),
|
||||||
|
};
|
||||||
|
|
||||||
|
let from_fn_arg = quote! {
|
||||||
|
#field_name: self.#field_name.get_untracked(),
|
||||||
|
};
|
||||||
|
|
||||||
|
new_fn_args.push(new_fn_arg);
|
||||||
|
from_fn_args.push(from_fn_arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
let reactive_docs = format!("Reactive version of the [`{name}`] struct. Automatically created by the `Reactive` macro.");
|
||||||
|
|
||||||
|
// Expand the macro. The output is a struct with new reactive fields and a new function,
|
||||||
|
// which initializes the reactive fields based on the original struct's fields.
|
||||||
|
let expanded = quote! {
|
||||||
|
use leptos::prelude::RwSignal as _RwSignal; // in case the user imports it themselves
|
||||||
|
use leptos::prelude::GetUntracked as _;
|
||||||
|
|
||||||
|
#[doc = #reactive_docs]
|
||||||
|
pub struct #reactive_name {
|
||||||
|
#(#new_fields)*
|
||||||
|
}
|
||||||
|
|
||||||
|
impl #reactive_name {
|
||||||
|
/// Creates a new `#reactive_name` struct from a non-reactive `#name`.
|
||||||
|
pub fn new(data: #name) -> Self {
|
||||||
|
Self {
|
||||||
|
#(#new_fn_args)*
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Captures the information of this struct into a `#name` struct, for use
|
||||||
|
/// in server functions.
|
||||||
|
pub fn capture(&self) -> #name {
|
||||||
|
#name {
|
||||||
|
#(#from_fn_args)*
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
TokenStream::from(expanded)
|
||||||
|
}
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 54 KiB |
@@ -0,0 +1,2 @@
|
|||||||
|
[rustfmt]
|
||||||
|
overrideCommand = ["leptosfmt", "--stdin", "--rustfmt"]
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
edition = "2021"
|
||||||
+46
-5
@@ -1,15 +1,15 @@
|
|||||||
use leptos::prelude::*;
|
use leptos::prelude::*;
|
||||||
use leptos_meta::{provide_meta_context, MetaTags, Stylesheet, Title};
|
use leptos_meta::{provide_meta_context, MetaTags, Stylesheet, Title};
|
||||||
|
use leptos_oidc::{
|
||||||
|
Auth, AuthLoaded, AuthParameters, AuthSignal, Authenticated, Challenge, LoginLink, LogoutLink,
|
||||||
|
};
|
||||||
use leptos_router::{
|
use leptos_router::{
|
||||||
components::{Route, Router, Routes},
|
components::{Route, Router, Routes},
|
||||||
StaticSegment,
|
StaticSegment,
|
||||||
};
|
};
|
||||||
|
use url::Url;
|
||||||
|
|
||||||
use crate::pages::{
|
use crate::pages::{AboutPage, HomePage, ProviderEntry};
|
||||||
AboutPage,
|
|
||||||
HomePage,
|
|
||||||
ProviderEntry
|
|
||||||
};
|
|
||||||
|
|
||||||
pub fn shell(options: LeptosOptions) -> impl IntoView {
|
pub fn shell(options: LeptosOptions) -> impl IntoView {
|
||||||
view! {
|
view! {
|
||||||
@@ -34,17 +34,38 @@ pub fn App() -> impl IntoView {
|
|||||||
// Provides context that manages stylesheets, titles, meta tags, etc.
|
// Provides context that manages stylesheets, titles, meta tags, etc.
|
||||||
provide_meta_context();
|
provide_meta_context();
|
||||||
|
|
||||||
|
// Authentication setup
|
||||||
|
let parameters = AuthParameters {
|
||||||
|
issuer: "https://cognito-idp.us-east-1.amazonaws.com/us-east-1_Lfjuy5zaM".into(),
|
||||||
|
client_id: "10jr2h3vtpu9n7gj46pvg5qo2q".into(),
|
||||||
|
redirect_uri: Url::parse("http://localhost:3000").unwrap().to_string(),
|
||||||
|
post_logout_redirect_uri: Url::parse("http://localhost:3000").unwrap().to_string(),
|
||||||
|
scope: Some("openid%20profile%20email".into()),
|
||||||
|
audience: None,
|
||||||
|
challenge: Challenge::None,
|
||||||
|
};
|
||||||
|
|
||||||
|
let auth = Auth::signal();
|
||||||
|
provide_context(auth); // allows use of this signal in lower areas of the tree without
|
||||||
|
// explicitly passing it through the html tree
|
||||||
|
|
||||||
|
let _ = Auth::init(parameters);
|
||||||
|
|
||||||
view! {
|
view! {
|
||||||
// injects a stylesheet into the document <head>
|
// injects a stylesheet into the document <head>
|
||||||
// id=leptos means cargo-leptos will hot-reload this stylesheet
|
// id=leptos means cargo-leptos will hot-reload this stylesheet
|
||||||
<Stylesheet id="leptos" href="/pkg/scholarships-rs-wasm.css"/>
|
<Stylesheet id="leptos" href="/pkg/scholarships-rs-wasm.css"/>
|
||||||
|
|
||||||
|
// <AuthLoading><p>"Authentication is loading"</p></AuthLoading>
|
||||||
|
// <AuthErrorContext><AuthErrorView/></AuthErrorContext>
|
||||||
|
|
||||||
// sets the document title
|
// sets the document title
|
||||||
<Title text="Welcome to Leptos"/>
|
<Title text="Welcome to Leptos"/>
|
||||||
|
|
||||||
// content for this welcome page
|
// content for this welcome page
|
||||||
<Router>
|
<Router>
|
||||||
<main>
|
<main>
|
||||||
|
// TODO Create a 404 page
|
||||||
<Routes fallback=|| "Page not found.".into_view()>
|
<Routes fallback=|| "Page not found.".into_view()>
|
||||||
<Route path=StaticSegment("") view=HomePage/>
|
<Route path=StaticSegment("") view=HomePage/>
|
||||||
<Route path=StaticSegment("about") view=AboutPage/>
|
<Route path=StaticSegment("about") view=AboutPage/>
|
||||||
@@ -54,3 +75,23 @@ pub fn App() -> impl IntoView {
|
|||||||
</Router>
|
</Router>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[component]
|
||||||
|
pub fn Unauthenticated() -> impl IntoView {
|
||||||
|
view! {
|
||||||
|
<p>"Error 401: Unauthorized"</p>
|
||||||
|
<LoginLink class="text-login">"Sign in"</LoginLink>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[component]
|
||||||
|
pub fn AuthErrorView() -> impl IntoView {
|
||||||
|
let auth = use_context::<AuthSignal>().expect("AuthError: RwSignal<AuthStore> was not found");
|
||||||
|
|
||||||
|
let error_message = move || auth.get().error().map(|error| format!("{error:?}"));
|
||||||
|
|
||||||
|
view! {
|
||||||
|
<h1>"An authentication error occurred."</h1>
|
||||||
|
{error_message}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,15 +1,14 @@
|
|||||||
|
use serde::{Deserialize, Serialize};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use serde::{Serialize, Deserialize};
|
|
||||||
|
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
struct FormDefinition {
|
struct FormDefinition {
|
||||||
sections: Vec<Section>
|
sections: Vec<Section>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
struct Section {
|
struct Section {
|
||||||
questions: Vec<QuestionType>
|
questions: Vec<QuestionType>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
@@ -20,12 +19,10 @@ enum QuestionType {
|
|||||||
Dropdown,
|
Dropdown,
|
||||||
Checkbox,
|
Checkbox,
|
||||||
Radio,
|
Radio,
|
||||||
Multi
|
Multi,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct TextInput {
|
struct TextInput {}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
struct QuestionComponent {
|
struct QuestionComponent {
|
||||||
@@ -34,5 +31,5 @@ struct QuestionComponent {
|
|||||||
placeholder: Option<String>,
|
placeholder: Option<String>,
|
||||||
|
|
||||||
// Used in <select> and <checkbox> elements
|
// Used in <select> and <checkbox> elements
|
||||||
options: Option<HashMap<String, String>>
|
options: Option<HashMap<String, String>>,
|
||||||
}
|
}
|
||||||
@@ -1,10 +1,9 @@
|
|||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct LoanerUser {
|
pub struct LoanerUser {
|
||||||
pub first_name: String,
|
pub first_name: String,
|
||||||
pub last_name: String,
|
pub last_name: String,
|
||||||
pub email: String,
|
pub email: String,
|
||||||
pub has_loan: bool
|
pub has_loan: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl LoanerUser {
|
impl LoanerUser {
|
||||||
@@ -13,7 +12,7 @@ impl LoanerUser {
|
|||||||
first_name: "".to_string(),
|
first_name: "".to_string(),
|
||||||
last_name: "".to_string(),
|
last_name: "".to_string(),
|
||||||
email: "".to_string(),
|
email: "".to_string(),
|
||||||
has_loan: false
|
has_loan: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+4
-6
@@ -1,8 +1,6 @@
|
|||||||
mod loaner_user;
|
|
||||||
mod student_info;
|
|
||||||
mod form_definition;
|
mod form_definition;
|
||||||
|
mod loaner_user;
|
||||||
|
mod student_info;
|
||||||
|
mod user;
|
||||||
|
|
||||||
pub use self::{
|
pub use self::{loaner_user::*, student_info::*, user::*};
|
||||||
loaner_user::*,
|
|
||||||
student_info::*
|
|
||||||
};
|
|
||||||
@@ -1,7 +1,9 @@
|
|||||||
use serde::{Deserialize, Serialize};
|
use macros::Reactive;
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug, Clone)]
|
#[derive(Serialize, Deserialize, Debug, Clone, Reactive)]
|
||||||
pub struct StudentInfo {
|
pub struct StudentInfo {
|
||||||
pub first_name: String,
|
pub first_name: String,
|
||||||
pub last_name: String,
|
pub last_name: String,
|
||||||
|
pub math_sat_score: i32,
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
// API URL to get user information from Google's Groups API:
|
||||||
|
// https://admin.googleapis.com/admin/directory/v1/groups?domain=region15.org&userKey=<email>
|
||||||
|
// Note that this requires a service account of some type, and that it should only be called from
|
||||||
|
// a pre-sign up lambda function.
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
|
pub struct UserClaims {
|
||||||
|
/// The time the JWT was issued, in UTC time.
|
||||||
|
#[serde(rename = "iat")]
|
||||||
|
issued_at: usize,
|
||||||
|
/// The issuer of the JWT.
|
||||||
|
#[serde(rename = "iss")]
|
||||||
|
issuer: String,
|
||||||
|
/// The time the JWT expires, in UTC time.
|
||||||
|
#[serde(rename = "exp")]
|
||||||
|
expiration_at: usize,
|
||||||
|
/// The subject of the JWT. This is the only unique identifier for a user.
|
||||||
|
#[serde(rename = "sub")]
|
||||||
|
pub subject: String,
|
||||||
|
/// The username of the user. This should be their email address.
|
||||||
|
#[serde(rename = "username")]
|
||||||
|
pub username: String,
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
use leptos::prelude::*;
|
||||||
|
|
||||||
|
#[component]
|
||||||
|
pub fn Checkbox(
|
||||||
|
#[prop()] checked: ReadSignal<bool>,
|
||||||
|
#[prop()] on_change: Callback<bool>,
|
||||||
|
#[prop()] label: String,
|
||||||
|
#[prop()] id: String
|
||||||
|
) -> impl IntoView {
|
||||||
|
let label_id = id.clone();
|
||||||
|
view! {
|
||||||
|
<label for=label_id>
|
||||||
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
id={id}
|
||||||
|
/>
|
||||||
|
</label>
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
use leptos::prelude::*;
|
||||||
|
|
||||||
|
#[component]
|
||||||
|
pub fn Loading() -> impl IntoView {
|
||||||
|
view! {
|
||||||
|
<div>
|
||||||
|
<img src="loading.gif" />
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,9 +1,8 @@
|
|||||||
mod action_button;
|
mod action_button;
|
||||||
mod text_field;
|
mod loading;
|
||||||
mod multi_entry;
|
mod multi_entry;
|
||||||
|
mod text_field;
|
||||||
|
mod select;
|
||||||
|
mod checkboxes;
|
||||||
|
|
||||||
pub use self::{
|
pub use self::{action_button::*, loading::*, multi_entry::*, text_field::*, select::*};
|
||||||
action_button::*,
|
|
||||||
text_field::*,
|
|
||||||
multi_entry::*
|
|
||||||
};
|
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
use crate::components::ActionButton;
|
||||||
use leptos::{leptos_dom::logging::console_log, prelude::*};
|
use leptos::{leptos_dom::logging::console_log, prelude::*};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
use crate::components::ActionButton;
|
|
||||||
|
|
||||||
#[derive(Clone, Serialize, Deserialize, Debug)]
|
#[derive(Clone, Serialize, Deserialize, Debug)]
|
||||||
pub struct MultiEntryData {
|
pub struct MultiEntryData {
|
||||||
@@ -27,7 +27,7 @@ pub struct MultiEntryMember {
|
|||||||
/// The name of the member, used for display only.
|
/// The name of the member, used for display only.
|
||||||
pub display_name: String,
|
pub display_name: String,
|
||||||
/// The actual name of the member, used to get the data from an Entry struct.
|
/// The actual name of the member, used to get the data from an Entry struct.
|
||||||
pub member_name: String
|
pub member_name: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MultiEntryMember {
|
impl MultiEntryMember {
|
||||||
@@ -35,7 +35,7 @@ impl MultiEntryMember {
|
|||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
display_name: String::new(),
|
display_name: String::new(),
|
||||||
member_name: String::new()
|
member_name: String::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -43,7 +43,7 @@ impl MultiEntryMember {
|
|||||||
pub fn from(display_name: String, member_name: String) -> Self {
|
pub fn from(display_name: String, member_name: String) -> Self {
|
||||||
Self {
|
Self {
|
||||||
display_name,
|
display_name,
|
||||||
member_name
|
member_name,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -51,7 +51,7 @@ impl MultiEntryMember {
|
|||||||
pub fn from_str(display_name: &str, member_name: &str) -> Self {
|
pub fn from_str(display_name: &str, member_name: &str) -> Self {
|
||||||
Self {
|
Self {
|
||||||
display_name: display_name.into(),
|
display_name: display_name.into(),
|
||||||
member_name: member_name.into()
|
member_name: member_name.into(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -85,9 +85,6 @@ pub fn Entry(
|
|||||||
/// The secondary display member for this entry.
|
/// The secondary display member for this entry.
|
||||||
#[prop()]
|
#[prop()]
|
||||||
info_member: Signal<MultiEntryMember>,
|
info_member: Signal<MultiEntryMember>,
|
||||||
/// The child components of this Entry view.
|
|
||||||
#[prop()]
|
|
||||||
children: Children
|
|
||||||
) -> impl IntoView {
|
) -> impl IntoView {
|
||||||
let nameData = entry_data.data.get(&name_member.get().member_name).unwrap();
|
let nameData = entry_data.data.get(&name_member.get().member_name).unwrap();
|
||||||
let infoData = entry_data.data.get(&info_member.get().member_name).unwrap();
|
let infoData = entry_data.data.get(&info_member.get().member_name).unwrap();
|
||||||
@@ -111,17 +108,19 @@ pub fn MultiEntry(
|
|||||||
name_member: Signal<MultiEntryMember>,
|
name_member: Signal<MultiEntryMember>,
|
||||||
/// The secondary display member for each entry object.
|
/// The secondary display member for each entry object.
|
||||||
#[prop()]
|
#[prop()]
|
||||||
info_member: Signal<MultiEntryMember>
|
info_member: Signal<MultiEntryMember>,
|
||||||
) -> impl IntoView {
|
) -> impl IntoView {
|
||||||
// Creates an entry in the given entries list.
|
// Creates an entry in the given entries list.
|
||||||
let create_entry = move |_| {
|
let create_entry = move |_| {
|
||||||
let mut new_entry = MultiEntryData::new();
|
let mut new_entry = MultiEntryData::new();
|
||||||
new_entry
|
new_entry.data.insert(
|
||||||
.data
|
name_member.get().member_name,
|
||||||
.insert(name_member.get().member_name, ValueType::String(String::from("Testing")));
|
ValueType::String(String::from("Testing")),
|
||||||
new_entry
|
);
|
||||||
.data
|
new_entry.data.insert(
|
||||||
.insert(info_member.get().member_name, ValueType::String(new_entry.id.to_string()));
|
info_member.get().member_name,
|
||||||
|
ValueType::String(new_entry.id.to_string()),
|
||||||
|
);
|
||||||
entries.update(|entry_vec| entry_vec.push(new_entry));
|
entries.update(|entry_vec| entry_vec.push(new_entry));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,38 @@
|
|||||||
|
use leptos::prelude::*;
|
||||||
|
|
||||||
|
/// A custom-styled select input.
|
||||||
|
///
|
||||||
|
/// Takes a `Vec<String>` as the set of inputs. Only one value may be selected, which is indicated
|
||||||
|
/// by the `value` prop of the component.
|
||||||
|
#[component]
|
||||||
|
pub fn Select(
|
||||||
|
#[prop(default = vec!["Test Value".into()])] value_list: Vec<String>,
|
||||||
|
#[prop(default = RwSignal::new("".into()))] value: RwSignal<String>,
|
||||||
|
#[prop(default = RwSignal::new("".into()))] label: RwSignal<String>,
|
||||||
|
#[prop(default = RwSignal::new(false))] disabled: RwSignal<bool>,
|
||||||
|
) -> impl IntoView {
|
||||||
|
view! {
|
||||||
|
<div>
|
||||||
|
<label>
|
||||||
|
{label}
|
||||||
|
<select
|
||||||
|
class="relative border-2 m-1.5 p-1.5 rounded-md"
|
||||||
|
class=(["border-red-700", "bg-transparent"], move || !disabled.get())
|
||||||
|
class=(["border-gray-600", "pointer-events-none", "bg-gray-600/33"], move || disabled.get())
|
||||||
|
on:change:target=move |e| {
|
||||||
|
value.set(e.target().value());
|
||||||
|
}>
|
||||||
|
// This closure handles the display of the options.
|
||||||
|
{move || {
|
||||||
|
value_list.iter().map(
|
||||||
|
move |value| {
|
||||||
|
let display = value.to_owned();
|
||||||
|
view! { <option value={display}>{display.clone()}</option> }
|
||||||
|
}
|
||||||
|
).collect::<Vec<_>>()
|
||||||
|
}}
|
||||||
|
</select>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,26 +1,39 @@
|
|||||||
|
use std::str::FromStr;
|
||||||
use leptos::prelude::*;
|
use leptos::prelude::*;
|
||||||
|
|
||||||
#[component]
|
#[component]
|
||||||
pub fn OutlinedTextField(
|
pub fn OutlinedTextField<T>(
|
||||||
#[prop(default = String::from(""))] placeholder: String,
|
#[prop(default = String::from(""))] placeholder: String,
|
||||||
#[prop(default = RwSignal::new("".to_string()))] value: RwSignal<String>,
|
#[prop(default = RwSignal::new(T::default()))] value: RwSignal<T>,
|
||||||
#[prop(default = RwSignal::new(false))] disabled: RwSignal<bool>,
|
#[prop(default = RwSignal::new(false))] disabled: RwSignal<bool>,
|
||||||
#[prop(default = String::from(""))] name: String,
|
#[prop(default = String::from(""))] name: String,
|
||||||
#[prop(default = String::from(""))] label: String,
|
#[prop(default = String::from(""))] label: String,
|
||||||
#[prop(default = String::from(""))] input_type: String,
|
#[prop(default = String::from(""))] input_type: String,
|
||||||
) -> impl IntoView {
|
) -> impl IntoView
|
||||||
|
where
|
||||||
|
T: Default + 'static + FromStr + ToString + PartialEq + Send + Sync + Clone
|
||||||
|
{
|
||||||
|
// Parsing logic for non-string types which happens on each input.
|
||||||
|
let on_input = move |e| {
|
||||||
|
let input_value = event_target_value(&e);
|
||||||
|
let parsed_value = T::from_str(&input_value)
|
||||||
|
.unwrap_or_default();
|
||||||
|
value.set(parsed_value);
|
||||||
|
};
|
||||||
|
|
||||||
view! (
|
view! (
|
||||||
<label>
|
<label>
|
||||||
{ label }
|
{ label }
|
||||||
<input
|
<input
|
||||||
class="border-2 m-1.5 p-1.5 rounded-md bg-transparent mt-6 relative transition-all duration-400"
|
class="border-2 m-1.5 p-1.5 rounded-md bg-transparent mt-6 relative transition-all duration-400"
|
||||||
class=(["border-red-700"], move || !disabled.get())
|
class=(["border-red-700", "bg-transparent"], move || !disabled.get())
|
||||||
class=(["border-gray-600", "pointer-events-none"], move || disabled.get())
|
class=(["border-gray-600", "pointer-events-none", "bg-gray-600/33"], move || disabled.get())
|
||||||
r#type={input_type}
|
r#type={input_type}
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
placeholder={placeholder}
|
placeholder={placeholder}
|
||||||
prop:name=name
|
prop:name=name
|
||||||
bind:value=value // This is a two-way binding - it is allowed to read *and* write.
|
prop:value={move || value.get().to_string()} // Sets the initial value.
|
||||||
|
on:input=on_input // Sets the value on each input.
|
||||||
/>
|
/>
|
||||||
</label>
|
</label>
|
||||||
)
|
)
|
||||||
|
|||||||
+3
-1
@@ -1,7 +1,9 @@
|
|||||||
|
use leptos::prelude::event_target_value;
|
||||||
|
|
||||||
pub mod app;
|
pub mod app;
|
||||||
|
mod common;
|
||||||
mod components;
|
mod components;
|
||||||
mod pages;
|
mod pages;
|
||||||
mod common;
|
|
||||||
|
|
||||||
#[cfg(feature = "hydrate")]
|
#[cfg(feature = "hydrate")]
|
||||||
#[wasm_bindgen::prelude::wasm_bindgen]
|
#[wasm_bindgen::prelude::wasm_bindgen]
|
||||||
|
|||||||
+125
-68
@@ -1,38 +1,54 @@
|
|||||||
use crate::components::{ActionButton, OutlinedTextField};
|
use std::collections::HashMap;
|
||||||
use crate::common::StudentInfo;
|
|
||||||
use leptos::leptos_dom::logging::console_log;
|
|
||||||
use leptos::prelude::*;
|
|
||||||
|
|
||||||
#[cfg(feature = "ssr")]
|
#[cfg(feature = "ssr")]
|
||||||
use aws_sdk_dynamodb::{error::ProvideErrorMetadata, types::AttributeValue, Client};
|
use aws_sdk_dynamodb::{error::ProvideErrorMetadata, types::AttributeValue, Client};
|
||||||
|
use crate::app::Unauthenticated;
|
||||||
|
use crate::common::{StudentInfo, StudentInfoReactive, UserClaims};
|
||||||
|
use crate::components::{ActionButton, Loading, OutlinedTextField, Select};
|
||||||
|
use leptos::leptos_dom::logging::console_log;
|
||||||
|
use leptos::prelude::*;
|
||||||
|
use leptos_oidc::{Algorithm, AuthLoaded, AuthSignal, Authenticated};
|
||||||
|
|
||||||
#[server(GetSubmission, endpoint = "/get-submission")]
|
#[server(GetSubmission, endpoint = "/get-submission")]
|
||||||
pub async fn get_submission(id: String) -> Result<StudentInfo, ServerFnError> {
|
pub async fn get_submission(id: String) -> Result<StudentInfo, ServerFnError> {
|
||||||
let config = aws_config::load_defaults(aws_config::BehaviorVersion::latest()).await;
|
let config = aws_config::load_defaults(aws_config::BehaviorVersion::latest()).await;
|
||||||
let dbclient = Client::new(&config);
|
let dbclient = Client::new(&config);
|
||||||
|
|
||||||
console_log(format!("Getting values from API using key {}", id).as_str());
|
console_log(format!("Getting values from API using username {}", id).as_str());
|
||||||
|
|
||||||
match dbclient
|
match dbclient
|
||||||
.get_item()
|
.get_item()
|
||||||
.table_name("student-applications")
|
.table_name("student-applications")
|
||||||
.key("Email", AttributeValue::S(id))
|
.key("Email", AttributeValue::S(id.clone()))
|
||||||
.send()
|
.send()
|
||||||
.await
|
.await
|
||||||
{
|
{
|
||||||
Ok(output) => {
|
Ok(output) => {
|
||||||
console_log("Found submission with passed key.");
|
|
||||||
let item = output.item.unwrap();
|
let item = output.item.unwrap();
|
||||||
let first_name = item
|
|
||||||
|
let first_name: String = item
|
||||||
.get("studentFirstName")
|
.get("studentFirstName")
|
||||||
.unwrap()
|
.and_then(|attr| attr.as_s().ok())
|
||||||
.as_s()
|
.map(|s| s.to_owned())
|
||||||
.unwrap()
|
.unwrap_or_default();
|
||||||
.clone();
|
|
||||||
let last_name = item.get("studentLastName").unwrap().as_s().unwrap().clone();
|
let last_name: String = item
|
||||||
|
.get("studentLastName")
|
||||||
|
.and_then(|attr| attr.as_s().ok())
|
||||||
|
.map(|s| s.to_owned())
|
||||||
|
.unwrap_or_default();
|
||||||
|
|
||||||
|
let math_sat_score = item
|
||||||
|
.get("mathSAT")
|
||||||
|
.and_then(|attr| attr.as_n().ok())
|
||||||
|
.map(|n| n.parse::<i32>().unwrap_or(0))
|
||||||
|
.unwrap_or_default();
|
||||||
|
|
||||||
|
console_log(format!("Got values from API: {} {}", first_name, last_name).as_str());
|
||||||
|
|
||||||
Ok(StudentInfo {
|
Ok(StudentInfo {
|
||||||
first_name,
|
first_name,
|
||||||
last_name,
|
last_name,
|
||||||
|
math_sat_score,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
@@ -43,7 +59,10 @@ pub async fn get_submission(id: String) -> Result<StudentInfo, ServerFnError> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[server(CreateSampleSubmission, endpoint = "/create-sample-submission")]
|
#[server(CreateSampleSubmission, endpoint = "/create-sample-submission")]
|
||||||
pub async fn create_sample_submission(student_info: StudentInfo) -> Result<(), ServerFnError> {
|
pub async fn create_sample_submission(
|
||||||
|
student_info: StudentInfo,
|
||||||
|
subject: String,
|
||||||
|
) -> Result<(), ServerFnError> {
|
||||||
use aws_sdk_dynamodb::{types::AttributeValue, Client};
|
use aws_sdk_dynamodb::{types::AttributeValue, Client};
|
||||||
|
|
||||||
let config = aws_config::load_defaults(aws_config::BehaviorVersion::latest()).await;
|
let config = aws_config::load_defaults(aws_config::BehaviorVersion::latest()).await;
|
||||||
@@ -51,18 +70,16 @@ pub async fn create_sample_submission(student_info: StudentInfo) -> Result<(), S
|
|||||||
|
|
||||||
console_log(
|
console_log(
|
||||||
format!(
|
format!(
|
||||||
"Creating sample submission with name {} {}",
|
"Creating sample submission with name {} {}, math score {}, and subject {}",
|
||||||
student_info.first_name, student_info.last_name
|
student_info.first_name, student_info.last_name, student_info.math_sat_score, subject
|
||||||
)
|
)
|
||||||
.as_str(),
|
.as_str(),
|
||||||
);
|
);
|
||||||
|
|
||||||
let submission_id = String::from("testing_student");
|
|
||||||
|
|
||||||
match dbclient
|
match dbclient
|
||||||
.update_item()
|
.update_item()
|
||||||
.table_name("student-applications")
|
.table_name("student-applications")
|
||||||
.key("Email", AttributeValue::S(submission_id))
|
.key("Email", AttributeValue::S(subject))
|
||||||
.expression_attribute_values(
|
.expression_attribute_values(
|
||||||
":studentFirstName",
|
":studentFirstName",
|
||||||
AttributeValue::S(student_info.first_name),
|
AttributeValue::S(student_info.first_name),
|
||||||
@@ -71,10 +88,17 @@ pub async fn create_sample_submission(student_info: StudentInfo) -> Result<(), S
|
|||||||
":studentLastName",
|
":studentLastName",
|
||||||
AttributeValue::S(student_info.last_name),
|
AttributeValue::S(student_info.last_name),
|
||||||
)
|
)
|
||||||
|
.expression_attribute_values(
|
||||||
|
":mathScoreSAT",
|
||||||
|
AttributeValue::N(student_info.math_sat_score.to_string()),
|
||||||
|
)
|
||||||
.expression_attribute_names("#studentFirstName", "studentFirstName")
|
.expression_attribute_names("#studentFirstName", "studentFirstName")
|
||||||
.expression_attribute_names("#studentLastName", "studentLastName")
|
.expression_attribute_names("#studentLastName", "studentLastName")
|
||||||
|
.expression_attribute_names("#mathScoreSAT", "mathScoreSAT")
|
||||||
.update_expression(
|
.update_expression(
|
||||||
"SET #studentFirstName = :studentFirstName, #studentLastName = :studentLastName",
|
concat!("SET #studentFirstName = :studentFirstName, ",
|
||||||
|
"#studentLastName = :studentLastName, ",
|
||||||
|
"#mathScoreSAT = :mathScoreSAT"),
|
||||||
)
|
)
|
||||||
.send()
|
.send()
|
||||||
.await
|
.await
|
||||||
@@ -86,65 +110,98 @@ pub async fn create_sample_submission(student_info: StudentInfo) -> Result<(), S
|
|||||||
|
|
||||||
#[component]
|
#[component]
|
||||||
pub fn HomePage() -> impl IntoView {
|
pub fn HomePage() -> impl IntoView {
|
||||||
let sample_id = RwSignal::new("google_113247439743075864879".to_string());
|
|
||||||
// Creates a reactive value to update the button
|
// Creates a reactive value to update the button
|
||||||
let count = RwSignal::new(0);
|
|
||||||
let elements_disabled = RwSignal::new(false);
|
|
||||||
|
|
||||||
|
let auth = use_context::<AuthSignal>().expect("Couldn't find user information.");
|
||||||
|
let user_claims = Signal::derive(move || {
|
||||||
|
auth.with(|auth| {
|
||||||
|
auth.authenticated().and_then(|data| {
|
||||||
|
data.decoded_access_token::<UserClaims>(Algorithm::RS256, &["account"])
|
||||||
|
})
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
// Note that the value passed in MUST be equatable.
|
||||||
|
// We get/unwrap the value repeatedly until we get a simple string value, then clone it so that
|
||||||
|
// we don't lose access to it in the future, should we need it again.
|
||||||
let server_resource = Resource::new(
|
let server_resource = Resource::new(
|
||||||
move || sample_id.get(),
|
move || user_claims.get().map(|claim| claim.claims.subject.clone()),
|
||||||
async |id| {
|
async |opt_username| match opt_username {
|
||||||
get_submission(id).await.unwrap_or_else(|e| {
|
Some(username) => get_submission(username).await.unwrap_or_else(|e| {
|
||||||
console_log(e.to_string().as_str());
|
console_log(e.to_string().as_str());
|
||||||
StudentInfo {
|
StudentInfo {
|
||||||
first_name: String::from("Error"),
|
first_name: String::from("Error"),
|
||||||
last_name: String::from(""),
|
last_name: String::from(""),
|
||||||
|
math_sat_score: 0,
|
||||||
}
|
}
|
||||||
})
|
}),
|
||||||
|
None => StudentInfo {
|
||||||
|
first_name: String::new(),
|
||||||
|
last_name: String::new(),
|
||||||
|
math_sat_score: 0,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
let on_click = move |_| {
|
|
||||||
*count.write() += 1;
|
|
||||||
*elements_disabled.write() = count.get() == 10;
|
|
||||||
};
|
|
||||||
let submit_action = ServerAction::<CreateSampleSubmission>::new();
|
let submit_action = ServerAction::<CreateSampleSubmission>::new();
|
||||||
|
|
||||||
view! {
|
view! {
|
||||||
<h1>"Welcome to Leptos!"</h1>
|
<AuthLoaded fallback=Loading>
|
||||||
<p>
|
<Authenticated unauthenticated=Unauthenticated>
|
||||||
"Lillian's reported full name from the API: "
|
// Replace this fallback with a real loading screen.
|
||||||
<Suspense fallback=move || view! { <span>"Loading..."</span> }>
|
<Suspense fallback=Loading>
|
||||||
{move || {
|
{move || {
|
||||||
server_resource.get().map(|submission| {
|
server_resource.get().map(|submission: StudentInfo| {
|
||||||
view! { <span>{submission.first_name}" "{submission.last_name}</span> }
|
let reactive_info = StudentInfoReactive::new(submission);
|
||||||
})
|
|
||||||
}}
|
let select_value = RwSignal::new(String::from("Math"));
|
||||||
</Suspense>
|
|
||||||
</p>
|
view! {
|
||||||
<ActionForm action=submit_action>
|
<p>
|
||||||
<div>
|
"Current user's reported full name from the API: "
|
||||||
<OutlinedTextField
|
{reactive_info.first_name}" "{reactive_info.last_name}
|
||||||
label="First Name".into()
|
</p>
|
||||||
placeholder="John".into()
|
|
||||||
disabled={elements_disabled}
|
<form>
|
||||||
name="student_info[first_name]".into() />
|
<div>
|
||||||
</div>
|
<OutlinedTextField
|
||||||
<div>
|
label="First Name".into()
|
||||||
<OutlinedTextField
|
placeholder="John".into()
|
||||||
label="Last Name".into()
|
value=reactive_info.first_name />
|
||||||
placeholder="Smith".into()
|
</div>
|
||||||
disabled={elements_disabled}
|
<div>
|
||||||
name="student_info[last_name]".into() />
|
<OutlinedTextField
|
||||||
</div>
|
label="Last Name".into()
|
||||||
<div>
|
placeholder="Smith".into()
|
||||||
<ActionButton
|
value=reactive_info.last_name />
|
||||||
on:click=on_click
|
</div>
|
||||||
disabled={elements_disabled}
|
<div>
|
||||||
button_type="submit".into()
|
<OutlinedTextField
|
||||||
>
|
label="Testing".into()
|
||||||
"Submit"
|
placeholder="Test".into()
|
||||||
</ActionButton>
|
value=reactive_info.math_sat_score />
|
||||||
</div>
|
</div>
|
||||||
</ActionForm>
|
<Select
|
||||||
|
value_list = vec!["Math".into(), "English".into(), "Science".into()]
|
||||||
|
value = select_value
|
||||||
|
/>
|
||||||
|
<div>
|
||||||
|
<ActionButton
|
||||||
|
on:click=move |_| {
|
||||||
|
submit_action.dispatch(CreateSampleSubmission {
|
||||||
|
student_info: reactive_info.capture(),
|
||||||
|
subject: user_claims.get().unwrap().claims.subject.clone()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
>
|
||||||
|
"Submit"
|
||||||
|
</ActionButton>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}}
|
||||||
|
</Suspense>
|
||||||
|
</Authenticated>
|
||||||
|
</AuthLoaded>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,23 +1,20 @@
|
|||||||
//! This defines the base component of the Chromebook loaner kiosk application.
|
//! This defines the base component of the Chromebook loaner kiosk application.
|
||||||
//! There are going to be 3 definitive screens that the users are able to see and use:
|
//! There are going to be 3 definitive screens that the users are able to see and use:
|
||||||
//! - The username entry screen: users will enter their name and email.
|
//! - The username entry screen: users will enter their name and email.
|
||||||
//! - The action selection screen: users will be given a choice regarding their loaner status.
|
//! - The action selection screen: users will be given a choice regarding their loaner status.
|
||||||
//! - The completion screen: users will be given a success message should their information save.
|
//! - The completion screen: users will be given a success message should their information save.
|
||||||
//! Refer to each component's file for more information about how they work.
|
//! Refer to each component's file for more information about how they work.
|
||||||
|
|
||||||
use leptos::prelude::*;
|
use super::{action_selection::ActionSelection, user_entry::UserEntry};
|
||||||
use crate::common::LoanerUser;
|
use crate::common::LoanerUser;
|
||||||
use super::{
|
use leptos::prelude::*;
|
||||||
user_entry::UserEntry,
|
|
||||||
action_selection::ActionSelection
|
|
||||||
};
|
|
||||||
|
|
||||||
/// Used to keep track of the currently displayed controls.
|
/// Used to keep track of the currently displayed controls.
|
||||||
#[derive(Clone, Copy, PartialEq)]
|
#[derive(Clone, Copy, PartialEq)]
|
||||||
pub enum LoanerKioskState {
|
pub enum LoanerKioskState {
|
||||||
UserEntry,
|
UserEntry,
|
||||||
ActionSelection,
|
ActionSelection,
|
||||||
Complete
|
Complete,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The base Chromebook loaner kiosk component.
|
/// The base Chromebook loaner kiosk component.
|
||||||
@@ -27,7 +24,7 @@ pub enum LoanerKioskState {
|
|||||||
pub fn LoanerKiosk() -> impl IntoView {
|
pub fn LoanerKiosk() -> impl IntoView {
|
||||||
let current_state = RwSignal::new(LoanerKioskState::UserEntry);
|
let current_state = RwSignal::new(LoanerKioskState::UserEntry);
|
||||||
let user = RwSignal::new(LoanerUser::new());
|
let user = RwSignal::new(LoanerUser::new());
|
||||||
|
|
||||||
view! {
|
view! {
|
||||||
<div class="flex w-screen h-screen justify-center items-center">
|
<div class="flex w-screen h-screen justify-center items-center">
|
||||||
<UserEntry
|
<UserEntry
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
mod loaner_kiosk;
|
|
||||||
mod user_entry;
|
|
||||||
mod action_selection;
|
mod action_selection;
|
||||||
|
mod loaner_kiosk;
|
||||||
|
mod user_entry;
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
//! Contains the user entry component.
|
//! Contains the user entry component.
|
||||||
//! It would be preferred if the user was restricted to a real user account. This is the URL:
|
//! It would be preferred if the user was restricted to a real user account. This is the URL:
|
||||||
//! https://admin.googleapis.com/admin/directory/v1/users?domain=region15.org&projection=BASIC&query=isArchived=false%20isAdmin=false
|
//! https://admin.googleapis.com/admin/directory/v1/users?domain=region15.org&projection=BASIC&query=isArchived=false%20isAdmin=false
|
||||||
//! Once they select this, they can then check in/out the loaners under their account.
|
//! Once they select this, they can then check in/out the loaners under their account.
|
||||||
@@ -6,10 +6,10 @@
|
|||||||
//! a service account. That's going to be a pain to set up.
|
//! a service account. That's going to be a pain to set up.
|
||||||
//! For example's sake here, we're just going to take a first name, last name, and email address.
|
//! For example's sake here, we're just going to take a first name, last name, and email address.
|
||||||
|
|
||||||
use leptos::leptos_dom::logging::console_log;
|
|
||||||
use leptos::prelude::*;
|
|
||||||
use crate::common::LoanerUser;
|
use crate::common::LoanerUser;
|
||||||
use crate::components::{ActionButton, OutlinedTextField};
|
use crate::components::{ActionButton, OutlinedTextField};
|
||||||
|
use leptos::leptos_dom::logging::console_log;
|
||||||
|
use leptos::prelude::*;
|
||||||
|
|
||||||
/// The user entry component for the loaner kiosk.
|
/// The user entry component for the loaner kiosk.
|
||||||
///
|
///
|
||||||
@@ -20,11 +20,14 @@ use crate::components::{ActionButton, OutlinedTextField};
|
|||||||
#[component]
|
#[component]
|
||||||
pub fn UserEntry(
|
pub fn UserEntry(
|
||||||
/// A callback function used when the control has determined this stage is finished.
|
/// A callback function used when the control has determined this stage is finished.
|
||||||
#[prop()] mut on_submit: impl FnMut() + 'static,
|
#[prop()]
|
||||||
|
mut on_submit: impl FnMut() + 'static,
|
||||||
/// The global user record.
|
/// The global user record.
|
||||||
#[prop()] user: RwSignal<LoanerUser>,
|
#[prop()]
|
||||||
|
user: RwSignal<LoanerUser>,
|
||||||
/// Whether this control is shown. Required for use with CSS animations.
|
/// Whether this control is shown. Required for use with CSS animations.
|
||||||
#[prop()] shown: bool
|
#[prop()]
|
||||||
|
shown: bool,
|
||||||
) -> impl IntoView {
|
) -> impl IntoView {
|
||||||
let disabled = RwSignal::new(false);
|
let disabled = RwSignal::new(false);
|
||||||
let on_click = move |_| {
|
let on_click = move |_| {
|
||||||
@@ -44,16 +47,19 @@ pub fn UserEntry(
|
|||||||
label="First Name".into()
|
label="First Name".into()
|
||||||
placeholder="John".into()
|
placeholder="John".into()
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
|
value=RwSignal::new("".to_owned())
|
||||||
/>
|
/>
|
||||||
<OutlinedTextField
|
<OutlinedTextField
|
||||||
label="Last Name".into()
|
label="Last Name".into()
|
||||||
placeholder="Smith".into()
|
placeholder="Smith".into()
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
|
value=RwSignal::new("".to_owned())
|
||||||
/>
|
/>
|
||||||
<OutlinedTextField
|
<OutlinedTextField
|
||||||
label="Region 15 Email".into()
|
label="Region 15 Email".into()
|
||||||
placeholder="jsmith@region15.org".into()
|
placeholder="jsmith@region15.org".into()
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
|
value=RwSignal::new("".to_owned())
|
||||||
/>
|
/>
|
||||||
<ActionButton
|
<ActionButton
|
||||||
on:click=on_click
|
on:click=on_click
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
mod about_page;
|
mod about_page;
|
||||||
mod home_page;
|
mod home_page;
|
||||||
mod provider_entry;
|
|
||||||
mod loaner_kiosk;
|
mod loaner_kiosk;
|
||||||
|
mod provider_entry;
|
||||||
|
|
||||||
pub use self::{about_page::*, home_page::*, provider_entry::*};
|
pub use self::{about_page::*, home_page::*, provider_entry::*};
|
||||||
+38
-19
@@ -1,27 +1,46 @@
|
|||||||
use crate::components::{MultiEntry, MultiEntryData, MultiEntryMember, OutlinedTextField};
|
use crate::app::Unauthenticated;
|
||||||
|
use crate::common::UserClaims;
|
||||||
|
use crate::components::{Loading, MultiEntry, MultiEntryData, MultiEntryMember, OutlinedTextField};
|
||||||
|
use leptos::leptos_dom::logging::console_log;
|
||||||
use leptos::prelude::*;
|
use leptos::prelude::*;
|
||||||
|
use leptos_oidc::{Algorithm, AuthLoaded, AuthSignal, Authenticated, LogoutLink};
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
#[component]
|
#[component]
|
||||||
pub fn ProviderEntry() -> impl IntoView {
|
pub fn ProviderEntry() -> impl IntoView {
|
||||||
|
let auth = use_context::<AuthSignal>().expect("Couldn't find auth signal");
|
||||||
|
let auth_data = auth
|
||||||
|
.get()
|
||||||
|
.authenticated()
|
||||||
|
.and_then(|data| data.decoded_access_token::<UserClaims>(Algorithm::RS256, &["account"]));
|
||||||
|
|
||||||
let multi_entries: RwSignal<Vec<MultiEntryData>> = RwSignal::new(vec![]);
|
let multi_entries: RwSignal<Vec<MultiEntryData>> = RwSignal::new(vec![]);
|
||||||
|
|
||||||
|
console_log(format!("User claims: {auth_data:?}").as_str());
|
||||||
|
|
||||||
view! (
|
view! (
|
||||||
<h1>This is the provider entry page</h1>
|
<AuthLoaded fallback=Loading>
|
||||||
<h2>It would usually have a series of questions that we ask the providers</h2>
|
<Authenticated unauthenticated=Unauthenticated>
|
||||||
<div>
|
<LogoutLink class="text-logout">"Sign out"</LogoutLink>
|
||||||
<OutlinedTextField
|
<h1>This is the provider entry page</h1>
|
||||||
placeholder = "Testing information...".into()
|
<h2>It would usually have a series of questions that we ask the providers</h2>
|
||||||
name = "testing_input".into()
|
<div>
|
||||||
label = "This is a testing question.".into()
|
<OutlinedTextField
|
||||||
/>
|
placeholder = "Testing information...".into()
|
||||||
</div>
|
name = "testing_input".into()
|
||||||
<div>
|
label = "This is a testing question.".into()
|
||||||
<p>This is an example of the multientry element.</p>
|
value = RwSignal::new("".to_owned())
|
||||||
<MultiEntry
|
/>
|
||||||
entries=multi_entries
|
</div>
|
||||||
name_member=Signal::from(MultiEntryMember::from_str("Entry Name", "name"))
|
<div>
|
||||||
info_member=Signal::from(MultiEntryMember::from_str("Entry Info", "info"))
|
<p>This is an example of the multientry element.</p>
|
||||||
/>
|
<MultiEntry
|
||||||
</div>
|
entries=multi_entries
|
||||||
|
name_member=Signal::from(MultiEntryMember::from_str("Entry Name", "name"))
|
||||||
|
info_member=Signal::from(MultiEntryMember::from_str("Entry Info", "info"))
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</Authenticated>
|
||||||
|
</AuthLoaded>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
Reference in new issue
Block a user