init
This commit is contained in:
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
/target
|
||||||
|
/logs
|
||||||
841
Cargo.lock
generated
Normal file
841
Cargo.lock
generated
Normal file
@@ -0,0 +1,841 @@
|
|||||||
|
# This file is automatically @generated by Cargo.
|
||||||
|
# It is not intended for manual editing.
|
||||||
|
version = 3
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "addr2line"
|
||||||
|
version = "0.17.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b9ecd88a8c8378ca913a680cd98f0f13ac67383d35993f86c90a70e3f137816b"
|
||||||
|
dependencies = [
|
||||||
|
"gimli",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "adler"
|
||||||
|
version = "1.0.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "anyhow"
|
||||||
|
version = "1.0.65"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "98161a4e3e2184da77bb14f02184cdd111e83bbbcc9979dfee3c44b9a85f5602"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "autocfg"
|
||||||
|
version = "1.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "backtrace"
|
||||||
|
version = "0.3.66"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cab84319d616cfb654d03394f38ab7e6f0919e181b1b57e1fd15e7fb4077d9a7"
|
||||||
|
dependencies = [
|
||||||
|
"addr2line",
|
||||||
|
"cc",
|
||||||
|
"cfg-if",
|
||||||
|
"libc",
|
||||||
|
"miniz_oxide",
|
||||||
|
"object",
|
||||||
|
"rustc-demangle",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bitmaps"
|
||||||
|
version = "2.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "031043d04099746d8db04daf1fa424b2bc8bd69d92b25962dcde24da39ab64a2"
|
||||||
|
dependencies = [
|
||||||
|
"typenum",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bumpalo"
|
||||||
|
version = "3.11.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c1ad822118d20d2c234f427000d5acc36eabe1e29a348c89b63dd60b13f28e5d"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "byteorder"
|
||||||
|
version = "1.4.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cc"
|
||||||
|
version = "1.0.73"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cfg-if"
|
||||||
|
version = "1.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "console_error_panic_hook"
|
||||||
|
version = "0.1.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a06aeb73f470f66dcdbf7223caeebb85984942f22f1adb2a088cf9668146bbbc"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"wasm-bindgen",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "dioxus"
|
||||||
|
version = "0.2.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "211119e0c96d2d0221ce1886b94aed18c41f7f9ccb23d0dc80fff5e919b2a1a2"
|
||||||
|
dependencies = [
|
||||||
|
"dioxus-core",
|
||||||
|
"dioxus-core-macro",
|
||||||
|
"dioxus-hooks",
|
||||||
|
"dioxus-html",
|
||||||
|
"dioxus-router",
|
||||||
|
"dioxus-web",
|
||||||
|
"fermi",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "dioxus-core"
|
||||||
|
version = "0.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "50fd75cb8f4752b122e3935eaa65b4c8c5c61dac2a305cb3d4c3422a01e0aee2"
|
||||||
|
dependencies = [
|
||||||
|
"backtrace",
|
||||||
|
"bumpalo",
|
||||||
|
"futures-channel",
|
||||||
|
"futures-util",
|
||||||
|
"fxhash",
|
||||||
|
"indexmap",
|
||||||
|
"log",
|
||||||
|
"longest-increasing-subsequence",
|
||||||
|
"once_cell",
|
||||||
|
"slab",
|
||||||
|
"smallvec",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "dioxus-core-macro"
|
||||||
|
version = "0.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "243fe485d0455d6f3645526970100a403fd037740af105cb5f175d8f4227baa6"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro-error",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "dioxus-hooks"
|
||||||
|
version = "0.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "51ffbb5b87c3bcd32a5629b5bd7921b7a7c685eded345c32100574b4a4df7872"
|
||||||
|
dependencies = [
|
||||||
|
"dioxus-core",
|
||||||
|
"futures-channel",
|
||||||
|
"log",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "dioxus-html"
|
||||||
|
version = "0.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c42fe33f30303e9acb0404e9c9aa61535ab50ad9e84f4809543881ee6a2b5abc"
|
||||||
|
dependencies = [
|
||||||
|
"dioxus-core",
|
||||||
|
"wasm-bindgen",
|
||||||
|
"web-sys",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "dioxus-html-macro"
|
||||||
|
version = "0.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7bdf706b1c5dfbfd2940ff116d2ddd433776b81a1900e31ced5884dfc45c5b11"
|
||||||
|
dependencies = [
|
||||||
|
"dioxus",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "dioxus-interpreter-js"
|
||||||
|
version = "0.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7d78a436643ca61ca4f5dec869fb91318c72068a013d2d5e21f9960810453b47"
|
||||||
|
dependencies = [
|
||||||
|
"js-sys",
|
||||||
|
"wasm-bindgen",
|
||||||
|
"web-sys",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "dioxus-router"
|
||||||
|
version = "0.2.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1d87ba54351495b657c291831de8f259be9616047f9e9826757788a43d3d2907"
|
||||||
|
dependencies = [
|
||||||
|
"dioxus-core",
|
||||||
|
"dioxus-core-macro",
|
||||||
|
"dioxus-html",
|
||||||
|
"futures-channel",
|
||||||
|
"futures-util",
|
||||||
|
"gloo-events",
|
||||||
|
"js-sys",
|
||||||
|
"log",
|
||||||
|
"serde",
|
||||||
|
"serde_urlencoded",
|
||||||
|
"thiserror",
|
||||||
|
"url",
|
||||||
|
"wasm-bindgen",
|
||||||
|
"web-sys",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "dioxus-web"
|
||||||
|
version = "0.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "61399ab0ebd255e3ad58c46cebc2a2db5d69a22af80bca68fe0a9aaf6480058f"
|
||||||
|
dependencies = [
|
||||||
|
"anyhow",
|
||||||
|
"console_error_panic_hook",
|
||||||
|
"dioxus-core",
|
||||||
|
"dioxus-html",
|
||||||
|
"dioxus-interpreter-js",
|
||||||
|
"futures-channel",
|
||||||
|
"futures-util",
|
||||||
|
"fxhash",
|
||||||
|
"gloo-timers",
|
||||||
|
"js-sys",
|
||||||
|
"log",
|
||||||
|
"once_cell",
|
||||||
|
"serde-wasm-bindgen",
|
||||||
|
"smallstr",
|
||||||
|
"wasm-bindgen",
|
||||||
|
"wasm-bindgen-futures",
|
||||||
|
"web-sys",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "fermi"
|
||||||
|
version = "0.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "aa3c170a3972c362a46622d09946b69c976c39832e24024c8efabe6073f8b995"
|
||||||
|
dependencies = [
|
||||||
|
"dioxus-core",
|
||||||
|
"im-rc",
|
||||||
|
"log",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "form_urlencoded"
|
||||||
|
version = "1.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a9c384f161156f5260c24a097c56119f9be8c798586aecc13afbcbe7b7e26bf8"
|
||||||
|
dependencies = [
|
||||||
|
"percent-encoding",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "futures-channel"
|
||||||
|
version = "0.3.24"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "30bdd20c28fadd505d0fd6712cdfcb0d4b5648baf45faef7f852afb2399bb050"
|
||||||
|
dependencies = [
|
||||||
|
"futures-core",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "futures-core"
|
||||||
|
version = "0.3.24"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4e5aa3de05362c3fb88de6531e6296e85cde7739cccad4b9dfeeb7f6ebce56bf"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "futures-macro"
|
||||||
|
version = "0.3.24"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "42cd15d1c7456c04dbdf7e88bcd69760d74f3a798d6444e16974b505b0e62f17"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "futures-task"
|
||||||
|
version = "0.3.24"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a6508c467c73851293f390476d4491cf4d227dbabcd4170f3bb6044959b294f1"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "futures-util"
|
||||||
|
version = "0.3.24"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "44fb6cb1be61cc1d2e43b262516aafcf63b241cffdb1d3fa115f91d9c7b09c90"
|
||||||
|
dependencies = [
|
||||||
|
"futures-core",
|
||||||
|
"futures-macro",
|
||||||
|
"futures-task",
|
||||||
|
"pin-project-lite",
|
||||||
|
"pin-utils",
|
||||||
|
"slab",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "fxhash"
|
||||||
|
version = "0.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c"
|
||||||
|
dependencies = [
|
||||||
|
"byteorder",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "gimli"
|
||||||
|
version = "0.26.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "22030e2c5a68ec659fde1e949a745124b48e6fa8b045b7ed5bd1fe4ccc5c4e5d"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "gloo-events"
|
||||||
|
version = "0.1.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "68b107f8abed8105e4182de63845afcc7b69c098b7852a813ea7462a320992fc"
|
||||||
|
dependencies = [
|
||||||
|
"wasm-bindgen",
|
||||||
|
"web-sys",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "gloo-timers"
|
||||||
|
version = "0.2.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5fb7d06c1c8cc2a29bee7ec961009a0b2caa0793ee4900c2ffb348734ba1c8f9"
|
||||||
|
dependencies = [
|
||||||
|
"futures-channel",
|
||||||
|
"futures-core",
|
||||||
|
"js-sys",
|
||||||
|
"wasm-bindgen",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hashbrown"
|
||||||
|
version = "0.12.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "idna"
|
||||||
|
version = "0.3.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e14ddfc70884202db2244c223200c204c2bda1bc6e0998d11b5e024d657209e6"
|
||||||
|
dependencies = [
|
||||||
|
"unicode-bidi",
|
||||||
|
"unicode-normalization",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "im-rc"
|
||||||
|
version = "15.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "af1955a75fa080c677d3972822ec4bad316169ab1cfc6c257a942c2265dbe5fe"
|
||||||
|
dependencies = [
|
||||||
|
"bitmaps",
|
||||||
|
"rand_core",
|
||||||
|
"rand_xoshiro",
|
||||||
|
"serde",
|
||||||
|
"sized-chunks",
|
||||||
|
"typenum",
|
||||||
|
"version_check",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "indexmap"
|
||||||
|
version = "1.9.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "10a35a97730320ffe8e2d410b5d3b69279b98d2c14bdb8b70ea89ecf7888d41e"
|
||||||
|
dependencies = [
|
||||||
|
"autocfg",
|
||||||
|
"hashbrown",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "itoa"
|
||||||
|
version = "1.0.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4217ad341ebadf8d8e724e264f13e593e0648f5b3e94b3896a5df283be015ecc"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "js-sys"
|
||||||
|
version = "0.3.60"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "49409df3e3bf0856b916e2ceaca09ee28e6871cf7d9ce97a692cacfdb2a25a47"
|
||||||
|
dependencies = [
|
||||||
|
"wasm-bindgen",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "lazy_static"
|
||||||
|
version = "1.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "libc"
|
||||||
|
version = "0.2.135"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "68783febc7782c6c5cb401fbda4de5a9898be1762314da0bb2c10ced61f18b0c"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "log"
|
||||||
|
version = "0.4.17"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "longest-increasing-subsequence"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b3bd0dd2cd90571056fdb71f6275fada10131182f84899f4b2a916e565d81d86"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "memchr"
|
||||||
|
version = "2.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "miniz_oxide"
|
||||||
|
version = "0.5.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "96590ba8f175222643a85693f33d26e9c8a015f599c216509b1a6894af675d34"
|
||||||
|
dependencies = [
|
||||||
|
"adler",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "object"
|
||||||
|
version = "0.29.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "21158b2c33aa6d4561f1c0a6ea283ca92bc54802a93b263e910746d679a7eb53"
|
||||||
|
dependencies = [
|
||||||
|
"memchr",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "once_cell"
|
||||||
|
version = "1.15.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e82dad04139b71a90c080c8463fe0dc7902db5192d939bd0950f074d014339e1"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "percent-encoding"
|
||||||
|
version = "2.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pin-project-lite"
|
||||||
|
version = "0.2.9"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pin-utils"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "proc-macro-error"
|
||||||
|
version = "1.0.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro-error-attr",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
"version_check",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "proc-macro-error-attr"
|
||||||
|
version = "1.0.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"version_check",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "proc-macro2"
|
||||||
|
version = "1.0.46"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "94e2ef8dbfc347b10c094890f778ee2e36ca9bb4262e86dc99cd217e35f3470b"
|
||||||
|
dependencies = [
|
||||||
|
"unicode-ident",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "quote"
|
||||||
|
version = "1.0.21"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "r-dashboard"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"console_error_panic_hook",
|
||||||
|
"dioxus",
|
||||||
|
"dioxus-html-macro",
|
||||||
|
"tracing",
|
||||||
|
"tracing-wasm",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rand_core"
|
||||||
|
version = "0.6.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rand_xoshiro"
|
||||||
|
version = "0.6.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6f97cdb2a36ed4183de61b2f824cc45c9f1037f28afe0a322e9fff4c108b5aaa"
|
||||||
|
dependencies = [
|
||||||
|
"rand_core",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustc-demangle"
|
||||||
|
version = "0.1.21"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7ef03e0a2b150c7a90d01faf6254c9c48a41e95fb2a8c2ac1c6f0d2b9aefc342"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ryu"
|
||||||
|
version = "1.0.11"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4501abdff3ae82a1c1b477a17252eb69cee9e66eb915c1abaa4f44d873df9f09"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde"
|
||||||
|
version = "1.0.145"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "728eb6351430bccb993660dfffc5a72f91ccc1295abaa8ce19b27ebe4f75568b"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde-wasm-bindgen"
|
||||||
|
version = "0.4.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e3b4c031cd0d9014307d82b8abf653c0290fbdaeb4c02d00c63cf52f728628bf"
|
||||||
|
dependencies = [
|
||||||
|
"js-sys",
|
||||||
|
"serde",
|
||||||
|
"wasm-bindgen",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde_urlencoded"
|
||||||
|
version = "0.7.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd"
|
||||||
|
dependencies = [
|
||||||
|
"form_urlencoded",
|
||||||
|
"itoa",
|
||||||
|
"ryu",
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "sharded-slab"
|
||||||
|
version = "0.1.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "900fba806f70c630b0a382d0d825e17a0f19fcd059a2ade1ff237bcddf446b31"
|
||||||
|
dependencies = [
|
||||||
|
"lazy_static",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "sized-chunks"
|
||||||
|
version = "0.6.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "16d69225bde7a69b235da73377861095455d298f2b970996eec25ddbb42b3d1e"
|
||||||
|
dependencies = [
|
||||||
|
"bitmaps",
|
||||||
|
"typenum",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "slab"
|
||||||
|
version = "0.4.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4614a76b2a8be0058caa9dbbaf66d988527d86d003c11a94fbd335d7661edcef"
|
||||||
|
dependencies = [
|
||||||
|
"autocfg",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "smallstr"
|
||||||
|
version = "0.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1e922794d168678729ffc7e07182721a14219c65814e66e91b839a272fe5ae4f"
|
||||||
|
dependencies = [
|
||||||
|
"smallvec",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "smallvec"
|
||||||
|
version = "1.10.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "syn"
|
||||||
|
version = "1.0.102"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3fcd952facd492f9be3ef0d0b7032a6e442ee9b361d4acc2b1d0c4aaa5f613a1"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"unicode-ident",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "thiserror"
|
||||||
|
version = "1.0.37"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "10deb33631e3c9018b9baf9dcbbc4f737320d2b576bac10f6aefa048fa407e3e"
|
||||||
|
dependencies = [
|
||||||
|
"thiserror-impl",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "thiserror-impl"
|
||||||
|
version = "1.0.37"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "982d17546b47146b28f7c22e3d08465f6b8903d0ea13c1660d9d84a6e7adcdbb"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "thread_local"
|
||||||
|
version = "1.1.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5516c27b78311c50bf42c071425c560ac799b11c30b31f87e3081965fe5e0180"
|
||||||
|
dependencies = [
|
||||||
|
"once_cell",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tinyvec"
|
||||||
|
version = "1.6.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50"
|
||||||
|
dependencies = [
|
||||||
|
"tinyvec_macros",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tinyvec_macros"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tracing"
|
||||||
|
version = "0.1.37"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"pin-project-lite",
|
||||||
|
"tracing-attributes",
|
||||||
|
"tracing-core",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tracing-attributes"
|
||||||
|
version = "0.1.23"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4017f8f45139870ca7e672686113917c71c7a6e02d4924eda67186083c03081a"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tracing-core"
|
||||||
|
version = "0.1.30"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "24eb03ba0eab1fd845050058ce5e616558e8f8d8fca633e6b163fe25c797213a"
|
||||||
|
dependencies = [
|
||||||
|
"once_cell",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tracing-subscriber"
|
||||||
|
version = "0.3.16"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a6176eae26dd70d0c919749377897b54a9276bd7061339665dd68777926b5a70"
|
||||||
|
dependencies = [
|
||||||
|
"sharded-slab",
|
||||||
|
"thread_local",
|
||||||
|
"tracing-core",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tracing-wasm"
|
||||||
|
version = "0.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4575c663a174420fa2d78f4108ff68f65bf2fbb7dd89f33749b6e826b3626e07"
|
||||||
|
dependencies = [
|
||||||
|
"tracing",
|
||||||
|
"tracing-subscriber",
|
||||||
|
"wasm-bindgen",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "typenum"
|
||||||
|
version = "1.15.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicode-bidi"
|
||||||
|
version = "0.3.8"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "099b7128301d285f79ddd55b9a83d5e6b9e97c92e0ea0daebee7263e932de992"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicode-ident"
|
||||||
|
version = "1.0.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6ceab39d59e4c9499d4e5a8ee0e2735b891bb7308ac83dfb4e80cad195c9f6f3"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicode-normalization"
|
||||||
|
version = "0.1.22"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921"
|
||||||
|
dependencies = [
|
||||||
|
"tinyvec",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "url"
|
||||||
|
version = "2.3.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0d68c799ae75762b8c3fe375feb6600ef5602c883c5d21eb51c09f22b83c4643"
|
||||||
|
dependencies = [
|
||||||
|
"form_urlencoded",
|
||||||
|
"idna",
|
||||||
|
"percent-encoding",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "version_check"
|
||||||
|
version = "0.9.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasm-bindgen"
|
||||||
|
version = "0.2.83"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "eaf9f5aceeec8be17c128b2e93e031fb8a4d469bb9c4ae2d7dc1888b26887268"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"wasm-bindgen-macro",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasm-bindgen-backend"
|
||||||
|
version = "0.2.83"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4c8ffb332579b0557b52d268b91feab8df3615f265d5270fec2a8c95b17c1142"
|
||||||
|
dependencies = [
|
||||||
|
"bumpalo",
|
||||||
|
"log",
|
||||||
|
"once_cell",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
"wasm-bindgen-shared",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasm-bindgen-futures"
|
||||||
|
version = "0.4.33"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "23639446165ca5a5de86ae1d8896b737ae80319560fbaa4c2887b7da6e7ebd7d"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"js-sys",
|
||||||
|
"wasm-bindgen",
|
||||||
|
"web-sys",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasm-bindgen-macro"
|
||||||
|
version = "0.2.83"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "052be0f94026e6cbc75cdefc9bae13fd6052cdcaf532fa6c45e7ae33a1e6c810"
|
||||||
|
dependencies = [
|
||||||
|
"quote",
|
||||||
|
"wasm-bindgen-macro-support",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasm-bindgen-macro-support"
|
||||||
|
version = "0.2.83"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "07bc0c051dc5f23e307b13285f9d75df86bfdf816c5721e573dec1f9b8aa193c"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
"wasm-bindgen-backend",
|
||||||
|
"wasm-bindgen-shared",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasm-bindgen-shared"
|
||||||
|
version = "0.2.83"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1c38c045535d93ec4f0b4defec448e4291638ee608530863b1e2ba115d4fff7f"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "web-sys"
|
||||||
|
version = "0.3.60"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bcda906d8be16e728fd5adc5b729afad4e444e106ab28cd1c7256e54fa61510f"
|
||||||
|
dependencies = [
|
||||||
|
"js-sys",
|
||||||
|
"wasm-bindgen",
|
||||||
|
]
|
||||||
14
Cargo.toml
Normal file
14
Cargo.toml
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
[package]
|
||||||
|
name = "r-dashboard"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
dioxus = {version = "0.2", features = ["web","router","fermi"]}
|
||||||
|
console_error_panic_hook = "0.1"
|
||||||
|
dioxus-html-macro = "0.2"
|
||||||
|
|
||||||
|
tracing = "0"
|
||||||
|
tracing-wasm = "0"
|
||||||
18
build.rs
Normal file
18
build.rs
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
/*
|
||||||
|
* @Author: plucky
|
||||||
|
* @Date: 2022-10-10 11:51:28
|
||||||
|
* @LastEditTime: 2022-10-15 13:43:11
|
||||||
|
* @Description:
|
||||||
|
*/
|
||||||
|
|
||||||
|
use std::process::Command;
|
||||||
|
|
||||||
|
fn main(){
|
||||||
|
// println!("hello, build.rs");
|
||||||
|
// tailwindcss -i index.css -o style.css
|
||||||
|
Command::new("tailwindcss").args(&["-i", "index.css", "-o", "dist/.stage/style.css"])
|
||||||
|
.status().unwrap();
|
||||||
|
// cp static/favicon.ico ... dist/.stage
|
||||||
|
Command::new("cp").args(&["static/favicon.ico", "...", "dist/.stage/"])
|
||||||
|
.status().unwrap();
|
||||||
|
}
|
||||||
BIN
dist/favicon.ico
vendored
Normal file
BIN
dist/favicon.ico
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.2 KiB |
43
dist/index.html
vendored
Normal file
43
dist/index.html
vendored
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
<!DOCTYPE html><html lang="en"><head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<link href="style.css" rel="stylesheet">
|
||||||
|
<link rel="stylesheet" href="https://rsms.me/inter/inter.css">
|
||||||
|
<title>Dashboard</title>
|
||||||
|
|
||||||
|
<link rel="preload" href="/r-dashboard-b0c35e8e84272a79_bg.wasm" as="fetch" type="application/wasm" crossorigin="">
|
||||||
|
<link rel="modulepreload" href="/r-dashboard-b0c35e8e84272a79.js"></head>
|
||||||
|
<body>
|
||||||
|
<div id="main"></div>
|
||||||
|
<div class="lg:hidden bg-black"></div>
|
||||||
|
|
||||||
|
|
||||||
|
<script type="module">import init from '/r-dashboard-b0c35e8e84272a79.js';init('/r-dashboard-b0c35e8e84272a79_bg.wasm');</script><script>(function () {
|
||||||
|
var protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';
|
||||||
|
var url = protocol + '//' + window.location.host + '/_trunk/ws';
|
||||||
|
var poll_interval = 5000;
|
||||||
|
var reload_upon_connect = () => {
|
||||||
|
window.setTimeout(
|
||||||
|
() => {
|
||||||
|
// when we successfully reconnect, we'll force a
|
||||||
|
// reload (since we presumably lost connection to
|
||||||
|
// trunk due to it being killed, so it will have
|
||||||
|
// rebuilt on restart)
|
||||||
|
var ws = new WebSocket(url);
|
||||||
|
ws.onopen = () => window.location.reload();
|
||||||
|
ws.onclose = reload_upon_connect;
|
||||||
|
},
|
||||||
|
poll_interval);
|
||||||
|
};
|
||||||
|
|
||||||
|
var ws = new WebSocket(url);
|
||||||
|
ws.onmessage = (ev) => {
|
||||||
|
const msg = JSON.parse(ev.data);
|
||||||
|
if (msg.reload) {
|
||||||
|
window.location.reload();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
ws.onclose = reload_upon_connect;
|
||||||
|
})()
|
||||||
|
</script></body></html>
|
||||||
1099
dist/r-dashboard-b0c35e8e84272a79.js
vendored
Normal file
1099
dist/r-dashboard-b0c35e8e84272a79.js
vendored
Normal file
File diff suppressed because it is too large
Load Diff
BIN
dist/r-dashboard-b0c35e8e84272a79_bg.wasm
vendored
Normal file
BIN
dist/r-dashboard-b0c35e8e84272a79_bg.wasm
vendored
Normal file
Binary file not shown.
603
dist/snippets/dioxus-interpreter-js-459fb15b86d869f7/src/interpreter.js
vendored
Normal file
603
dist/snippets/dioxus-interpreter-js-459fb15b86d869f7/src/interpreter.js
vendored
Normal file
@@ -0,0 +1,603 @@
|
|||||||
|
export function main() {
|
||||||
|
let root = window.document.getElementById("main");
|
||||||
|
if (root != null) {
|
||||||
|
window.interpreter = new Interpreter(root);
|
||||||
|
window.ipc.postMessage(serializeIpcMessage("initialize"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
export class Interpreter {
|
||||||
|
constructor(root) {
|
||||||
|
this.root = root;
|
||||||
|
this.stack = [root];
|
||||||
|
this.listeners = {};
|
||||||
|
this.handlers = {};
|
||||||
|
this.lastNodeWasText = false;
|
||||||
|
this.nodes = [root];
|
||||||
|
}
|
||||||
|
top() {
|
||||||
|
return this.stack[this.stack.length - 1];
|
||||||
|
}
|
||||||
|
pop() {
|
||||||
|
return this.stack.pop();
|
||||||
|
}
|
||||||
|
SetNode(id, node) {
|
||||||
|
this.nodes[id] = node;
|
||||||
|
}
|
||||||
|
PushRoot(root) {
|
||||||
|
const node = this.nodes[root];
|
||||||
|
this.stack.push(node);
|
||||||
|
}
|
||||||
|
PopRoot() {
|
||||||
|
this.stack.pop();
|
||||||
|
}
|
||||||
|
AppendChildren(many) {
|
||||||
|
let root = this.stack[this.stack.length - (1 + many)];
|
||||||
|
let to_add = this.stack.splice(this.stack.length - many);
|
||||||
|
for (let i = 0; i < many; i++) {
|
||||||
|
root.appendChild(to_add[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ReplaceWith(root_id, m) {
|
||||||
|
let root = this.nodes[root_id];
|
||||||
|
let els = this.stack.splice(this.stack.length - m);
|
||||||
|
root.replaceWith(...els);
|
||||||
|
}
|
||||||
|
InsertAfter(root, n) {
|
||||||
|
let old = this.nodes[root];
|
||||||
|
let new_nodes = this.stack.splice(this.stack.length - n);
|
||||||
|
old.after(...new_nodes);
|
||||||
|
}
|
||||||
|
InsertBefore(root, n) {
|
||||||
|
let old = this.nodes[root];
|
||||||
|
let new_nodes = this.stack.splice(this.stack.length - n);
|
||||||
|
old.before(...new_nodes);
|
||||||
|
}
|
||||||
|
Remove(root) {
|
||||||
|
let node = this.nodes[root];
|
||||||
|
if (node !== undefined) {
|
||||||
|
node.remove();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
CreateTextNode(text, root) {
|
||||||
|
const node = document.createTextNode(text);
|
||||||
|
this.nodes[root] = node;
|
||||||
|
this.stack.push(node);
|
||||||
|
}
|
||||||
|
CreateElement(tag, root) {
|
||||||
|
const el = document.createElement(tag);
|
||||||
|
this.nodes[root] = el;
|
||||||
|
this.stack.push(el);
|
||||||
|
}
|
||||||
|
CreateElementNs(tag, root, ns) {
|
||||||
|
let el = document.createElementNS(ns, tag);
|
||||||
|
this.stack.push(el);
|
||||||
|
this.nodes[root] = el;
|
||||||
|
}
|
||||||
|
CreatePlaceholder(root) {
|
||||||
|
let el = document.createElement("pre");
|
||||||
|
el.hidden = true;
|
||||||
|
this.stack.push(el);
|
||||||
|
this.nodes[root] = el;
|
||||||
|
}
|
||||||
|
NewEventListener(event_name, root, handler) {
|
||||||
|
const element = this.nodes[root];
|
||||||
|
element.setAttribute("data-dioxus-id", `${root}`);
|
||||||
|
if (this.listeners[event_name] === undefined) {
|
||||||
|
this.listeners[event_name] = 1;
|
||||||
|
this.handlers[event_name] = handler;
|
||||||
|
this.root.addEventListener(event_name, handler);
|
||||||
|
} else {
|
||||||
|
this.listeners[event_name]++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
RemoveEventListener(root, event_name) {
|
||||||
|
const element = this.nodes[root];
|
||||||
|
element.removeAttribute(`data-dioxus-id`);
|
||||||
|
this.listeners[event_name]--;
|
||||||
|
if (this.listeners[event_name] === 0) {
|
||||||
|
this.root.removeEventListener(event_name, this.handlers[event_name]);
|
||||||
|
delete this.listeners[event_name];
|
||||||
|
delete this.handlers[event_name];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SetText(root, text) {
|
||||||
|
this.nodes[root].textContent = text;
|
||||||
|
}
|
||||||
|
SetAttribute(root, field, value, ns) {
|
||||||
|
const name = field;
|
||||||
|
const node = this.nodes[root];
|
||||||
|
if (ns === "style") {
|
||||||
|
// @ts-ignore
|
||||||
|
node.style[name] = value;
|
||||||
|
} else if (ns != null || ns != undefined) {
|
||||||
|
node.setAttributeNS(ns, name, value);
|
||||||
|
} else {
|
||||||
|
switch (name) {
|
||||||
|
case "value":
|
||||||
|
if (value !== node.value) {
|
||||||
|
node.value = value;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "checked":
|
||||||
|
node.checked = value === "true";
|
||||||
|
break;
|
||||||
|
case "selected":
|
||||||
|
node.selected = value === "true";
|
||||||
|
break;
|
||||||
|
case "dangerous_inner_html":
|
||||||
|
node.innerHTML = value;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// https://github.com/facebook/react/blob/8b88ac2592c5f555f315f9440cbb665dd1e7457a/packages/react-dom/src/shared/DOMProperty.js#L352-L364
|
||||||
|
if (value === "false" && bool_attrs.hasOwnProperty(name)) {
|
||||||
|
node.removeAttribute(name);
|
||||||
|
} else {
|
||||||
|
node.setAttribute(name, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
RemoveAttribute(root, field, ns) {
|
||||||
|
const name = field;
|
||||||
|
const node = this.nodes[root];
|
||||||
|
if (ns !== null || ns !== undefined) {
|
||||||
|
node.removeAttributeNS(ns, name);
|
||||||
|
} else if (name === "value") {
|
||||||
|
node.value = "";
|
||||||
|
} else if (name === "checked") {
|
||||||
|
node.checked = false;
|
||||||
|
} else if (name === "selected") {
|
||||||
|
node.selected = false;
|
||||||
|
} else if (name === "dangerous_inner_html") {
|
||||||
|
node.innerHTML = "";
|
||||||
|
} else {
|
||||||
|
node.removeAttribute(name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
handleEdits(edits) {
|
||||||
|
this.stack.push(this.root);
|
||||||
|
for (let edit of edits) {
|
||||||
|
this.handleEdit(edit);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
handleEdit(edit) {
|
||||||
|
switch (edit.type) {
|
||||||
|
case "PushRoot":
|
||||||
|
this.PushRoot(edit.root);
|
||||||
|
break;
|
||||||
|
case "AppendChildren":
|
||||||
|
this.AppendChildren(edit.many);
|
||||||
|
break;
|
||||||
|
case "ReplaceWith":
|
||||||
|
this.ReplaceWith(edit.root, edit.m);
|
||||||
|
break;
|
||||||
|
case "InsertAfter":
|
||||||
|
this.InsertAfter(edit.root, edit.n);
|
||||||
|
break;
|
||||||
|
case "InsertBefore":
|
||||||
|
this.InsertBefore(edit.root, edit.n);
|
||||||
|
break;
|
||||||
|
case "Remove":
|
||||||
|
this.Remove(edit.root);
|
||||||
|
break;
|
||||||
|
case "CreateTextNode":
|
||||||
|
this.CreateTextNode(edit.text, edit.root);
|
||||||
|
break;
|
||||||
|
case "CreateElement":
|
||||||
|
this.CreateElement(edit.tag, edit.root);
|
||||||
|
break;
|
||||||
|
case "CreateElementNs":
|
||||||
|
this.CreateElementNs(edit.tag, edit.root, edit.ns);
|
||||||
|
break;
|
||||||
|
case "CreatePlaceholder":
|
||||||
|
this.CreatePlaceholder(edit.root);
|
||||||
|
break;
|
||||||
|
case "RemoveEventListener":
|
||||||
|
this.RemoveEventListener(edit.root, edit.event_name);
|
||||||
|
break;
|
||||||
|
case "NewEventListener":
|
||||||
|
console.log(this.listeners);
|
||||||
|
|
||||||
|
// this handler is only provided on desktop implementations since this
|
||||||
|
// method is not used by the web implementation
|
||||||
|
let handler = (event) => {
|
||||||
|
console.log(event);
|
||||||
|
|
||||||
|
let target = event.target;
|
||||||
|
if (target != null) {
|
||||||
|
let realId = target.getAttribute(`data-dioxus-id`);
|
||||||
|
let shouldPreventDefault = target.getAttribute(
|
||||||
|
`dioxus-prevent-default`
|
||||||
|
);
|
||||||
|
|
||||||
|
if (event.type === "click") {
|
||||||
|
// todo call prevent default if it's the right type of event
|
||||||
|
if (shouldPreventDefault !== `onclick`) {
|
||||||
|
if (target.tagName === "A") {
|
||||||
|
event.preventDefault();
|
||||||
|
const href = target.getAttribute("href");
|
||||||
|
if (href !== "" && href !== null && href !== undefined) {
|
||||||
|
window.ipc.postMessage(
|
||||||
|
serializeIpcMessage("browser_open", { href })
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// also prevent buttons from submitting
|
||||||
|
if (target.tagName === "BUTTON" && event.type == "submit") {
|
||||||
|
event.preventDefault();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// walk the tree to find the real element
|
||||||
|
while (realId == null) {
|
||||||
|
// we've reached the root we don't want to send an event
|
||||||
|
if (target.parentElement === null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
target = target.parentElement;
|
||||||
|
realId = target.getAttribute(`data-dioxus-id`);
|
||||||
|
}
|
||||||
|
|
||||||
|
shouldPreventDefault = target.getAttribute(
|
||||||
|
`dioxus-prevent-default`
|
||||||
|
);
|
||||||
|
|
||||||
|
let contents = serialize_event(event);
|
||||||
|
|
||||||
|
if (shouldPreventDefault === `on${event.type}`) {
|
||||||
|
event.preventDefault();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (event.type === "submit") {
|
||||||
|
event.preventDefault();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
target.tagName === "FORM" &&
|
||||||
|
(event.type === "submit" || event.type === "input")
|
||||||
|
) {
|
||||||
|
for (let x = 0; x < target.elements.length; x++) {
|
||||||
|
let element = target.elements[x];
|
||||||
|
let name = element.getAttribute("name");
|
||||||
|
if (name != null) {
|
||||||
|
if (element.getAttribute("type") === "checkbox") {
|
||||||
|
// @ts-ignore
|
||||||
|
contents.values[name] = element.checked ? "true" : "false";
|
||||||
|
} else if (element.getAttribute("type") === "radio") {
|
||||||
|
if (element.checked) {
|
||||||
|
contents.values[name] = element.value;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// @ts-ignore
|
||||||
|
contents.values[name] =
|
||||||
|
element.value ?? element.textContent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (realId === null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
window.ipc.postMessage(
|
||||||
|
serializeIpcMessage("user_event", {
|
||||||
|
event: edit.event_name,
|
||||||
|
mounted_dom_id: parseInt(realId),
|
||||||
|
contents: contents,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
this.NewEventListener(edit.event_name, edit.root, handler);
|
||||||
|
break;
|
||||||
|
case "SetText":
|
||||||
|
this.SetText(edit.root, edit.text);
|
||||||
|
break;
|
||||||
|
case "SetAttribute":
|
||||||
|
this.SetAttribute(edit.root, edit.field, edit.value, edit.ns);
|
||||||
|
break;
|
||||||
|
case "RemoveAttribute":
|
||||||
|
this.RemoveAttribute(edit.root, edit.name, edit.ns);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function serialize_event(event) {
|
||||||
|
switch (event.type) {
|
||||||
|
case "copy":
|
||||||
|
case "cut":
|
||||||
|
case "past": {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
case "compositionend":
|
||||||
|
case "compositionstart":
|
||||||
|
case "compositionupdate": {
|
||||||
|
let { data } = event;
|
||||||
|
return {
|
||||||
|
data,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
case "keydown":
|
||||||
|
case "keypress":
|
||||||
|
case "keyup": {
|
||||||
|
let {
|
||||||
|
charCode,
|
||||||
|
key,
|
||||||
|
altKey,
|
||||||
|
ctrlKey,
|
||||||
|
metaKey,
|
||||||
|
keyCode,
|
||||||
|
shiftKey,
|
||||||
|
location,
|
||||||
|
repeat,
|
||||||
|
which,
|
||||||
|
} = event;
|
||||||
|
return {
|
||||||
|
char_code: charCode,
|
||||||
|
key: key,
|
||||||
|
alt_key: altKey,
|
||||||
|
ctrl_key: ctrlKey,
|
||||||
|
meta_key: metaKey,
|
||||||
|
key_code: keyCode,
|
||||||
|
shift_key: shiftKey,
|
||||||
|
location: location,
|
||||||
|
repeat: repeat,
|
||||||
|
which: which,
|
||||||
|
locale: "locale",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
case "focus":
|
||||||
|
case "blur": {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
case "change": {
|
||||||
|
let target = event.target;
|
||||||
|
let value;
|
||||||
|
if (target.type === "checkbox" || target.type === "radio") {
|
||||||
|
value = target.checked ? "true" : "false";
|
||||||
|
} else {
|
||||||
|
value = target.value ?? target.textContent;
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
value: value,
|
||||||
|
values: {},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
case "input":
|
||||||
|
case "invalid":
|
||||||
|
case "reset":
|
||||||
|
case "submit": {
|
||||||
|
let target = event.target;
|
||||||
|
let value = target.value ?? target.textContent;
|
||||||
|
|
||||||
|
if (target.type === "checkbox") {
|
||||||
|
value = target.checked ? "true" : "false";
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
value: value,
|
||||||
|
values: {},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
case "click":
|
||||||
|
case "contextmenu":
|
||||||
|
case "doubleclick":
|
||||||
|
case "dblclick":
|
||||||
|
case "drag":
|
||||||
|
case "dragend":
|
||||||
|
case "dragenter":
|
||||||
|
case "dragexit":
|
||||||
|
case "dragleave":
|
||||||
|
case "dragover":
|
||||||
|
case "dragstart":
|
||||||
|
case "drop":
|
||||||
|
case "mousedown":
|
||||||
|
case "mouseenter":
|
||||||
|
case "mouseleave":
|
||||||
|
case "mousemove":
|
||||||
|
case "mouseout":
|
||||||
|
case "mouseover":
|
||||||
|
case "mouseup": {
|
||||||
|
const {
|
||||||
|
altKey,
|
||||||
|
button,
|
||||||
|
buttons,
|
||||||
|
clientX,
|
||||||
|
clientY,
|
||||||
|
ctrlKey,
|
||||||
|
metaKey,
|
||||||
|
pageX,
|
||||||
|
pageY,
|
||||||
|
screenX,
|
||||||
|
screenY,
|
||||||
|
shiftKey,
|
||||||
|
} = event;
|
||||||
|
return {
|
||||||
|
alt_key: altKey,
|
||||||
|
button: button,
|
||||||
|
buttons: buttons,
|
||||||
|
client_x: clientX,
|
||||||
|
client_y: clientY,
|
||||||
|
ctrl_key: ctrlKey,
|
||||||
|
meta_key: metaKey,
|
||||||
|
page_x: pageX,
|
||||||
|
page_y: pageY,
|
||||||
|
screen_x: screenX,
|
||||||
|
screen_y: screenY,
|
||||||
|
shift_key: shiftKey,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
case "pointerdown":
|
||||||
|
case "pointermove":
|
||||||
|
case "pointerup":
|
||||||
|
case "pointercancel":
|
||||||
|
case "gotpointercapture":
|
||||||
|
case "lostpointercapture":
|
||||||
|
case "pointerenter":
|
||||||
|
case "pointerleave":
|
||||||
|
case "pointerover":
|
||||||
|
case "pointerout": {
|
||||||
|
const {
|
||||||
|
altKey,
|
||||||
|
button,
|
||||||
|
buttons,
|
||||||
|
clientX,
|
||||||
|
clientY,
|
||||||
|
ctrlKey,
|
||||||
|
metaKey,
|
||||||
|
pageX,
|
||||||
|
pageY,
|
||||||
|
screenX,
|
||||||
|
screenY,
|
||||||
|
shiftKey,
|
||||||
|
pointerId,
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
pressure,
|
||||||
|
tangentialPressure,
|
||||||
|
tiltX,
|
||||||
|
tiltY,
|
||||||
|
twist,
|
||||||
|
pointerType,
|
||||||
|
isPrimary,
|
||||||
|
} = event;
|
||||||
|
return {
|
||||||
|
alt_key: altKey,
|
||||||
|
button: button,
|
||||||
|
buttons: buttons,
|
||||||
|
client_x: clientX,
|
||||||
|
client_y: clientY,
|
||||||
|
ctrl_key: ctrlKey,
|
||||||
|
meta_key: metaKey,
|
||||||
|
page_x: pageX,
|
||||||
|
page_y: pageY,
|
||||||
|
screen_x: screenX,
|
||||||
|
screen_y: screenY,
|
||||||
|
shift_key: shiftKey,
|
||||||
|
pointer_id: pointerId,
|
||||||
|
width: width,
|
||||||
|
height: height,
|
||||||
|
pressure: pressure,
|
||||||
|
tangential_pressure: tangentialPressure,
|
||||||
|
tilt_x: tiltX,
|
||||||
|
tilt_y: tiltY,
|
||||||
|
twist: twist,
|
||||||
|
pointer_type: pointerType,
|
||||||
|
is_primary: isPrimary,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
case "select": {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
case "touchcancel":
|
||||||
|
case "touchend":
|
||||||
|
case "touchmove":
|
||||||
|
case "touchstart": {
|
||||||
|
const { altKey, ctrlKey, metaKey, shiftKey } = event;
|
||||||
|
return {
|
||||||
|
// changed_touches: event.changedTouches,
|
||||||
|
// target_touches: event.targetTouches,
|
||||||
|
// touches: event.touches,
|
||||||
|
alt_key: altKey,
|
||||||
|
ctrl_key: ctrlKey,
|
||||||
|
meta_key: metaKey,
|
||||||
|
shift_key: shiftKey,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
case "scroll": {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
case "wheel": {
|
||||||
|
const { deltaX, deltaY, deltaZ, deltaMode } = event;
|
||||||
|
return {
|
||||||
|
delta_x: deltaX,
|
||||||
|
delta_y: deltaY,
|
||||||
|
delta_z: deltaZ,
|
||||||
|
delta_mode: deltaMode,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
case "animationstart":
|
||||||
|
case "animationend":
|
||||||
|
case "animationiteration": {
|
||||||
|
const { animationName, elapsedTime, pseudoElement } = event;
|
||||||
|
return {
|
||||||
|
animation_name: animationName,
|
||||||
|
elapsed_time: elapsedTime,
|
||||||
|
pseudo_element: pseudoElement,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
case "transitionend": {
|
||||||
|
const { propertyName, elapsedTime, pseudoElement } = event;
|
||||||
|
return {
|
||||||
|
property_name: propertyName,
|
||||||
|
elapsed_time: elapsedTime,
|
||||||
|
pseudo_element: pseudoElement,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
case "abort":
|
||||||
|
case "canplay":
|
||||||
|
case "canplaythrough":
|
||||||
|
case "durationchange":
|
||||||
|
case "emptied":
|
||||||
|
case "encrypted":
|
||||||
|
case "ended":
|
||||||
|
case "error":
|
||||||
|
case "loadeddata":
|
||||||
|
case "loadedmetadata":
|
||||||
|
case "loadstart":
|
||||||
|
case "pause":
|
||||||
|
case "play":
|
||||||
|
case "playing":
|
||||||
|
case "progress":
|
||||||
|
case "ratechange":
|
||||||
|
case "seeked":
|
||||||
|
case "seeking":
|
||||||
|
case "stalled":
|
||||||
|
case "suspend":
|
||||||
|
case "timeupdate":
|
||||||
|
case "volumechange":
|
||||||
|
case "waiting": {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
case "toggle": {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function serializeIpcMessage(method, params = {}) {
|
||||||
|
return JSON.stringify({ method, params });
|
||||||
|
}
|
||||||
|
const bool_attrs = {
|
||||||
|
allowfullscreen: true,
|
||||||
|
allowpaymentrequest: true,
|
||||||
|
async: true,
|
||||||
|
autofocus: true,
|
||||||
|
autoplay: true,
|
||||||
|
checked: true,
|
||||||
|
controls: true,
|
||||||
|
default: true,
|
||||||
|
defer: true,
|
||||||
|
disabled: true,
|
||||||
|
formnovalidate: true,
|
||||||
|
hidden: true,
|
||||||
|
ismap: true,
|
||||||
|
itemscope: true,
|
||||||
|
loop: true,
|
||||||
|
multiple: true,
|
||||||
|
muted: true,
|
||||||
|
nomodule: true,
|
||||||
|
novalidate: true,
|
||||||
|
open: true,
|
||||||
|
playsinline: true,
|
||||||
|
readonly: true,
|
||||||
|
required: true,
|
||||||
|
reversed: true,
|
||||||
|
selected: true,
|
||||||
|
truespeed: true,
|
||||||
|
};
|
||||||
2137
dist/style.css
vendored
Normal file
2137
dist/style.css
vendored
Normal file
File diff suppressed because it is too large
Load Diff
12
index.css
Normal file
12
index.css
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
@tailwind base;
|
||||||
|
@tailwind components;
|
||||||
|
@tailwind utilities;
|
||||||
|
|
||||||
|
|
||||||
|
.btn {
|
||||||
|
@apply py-2 px-4 font-semibold rounded-lg shadow-md;
|
||||||
|
}
|
||||||
|
.btn-green {
|
||||||
|
@apply text-white bg-green-500 hover:bg-green-700;
|
||||||
|
}
|
||||||
|
|
||||||
16
index.html
Normal file
16
index.html
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<link href="style.css" rel="stylesheet">
|
||||||
|
<link rel="stylesheet" href="https://rsms.me/inter/inter.css">
|
||||||
|
<title>Dashboard</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="main"></div>
|
||||||
|
<div class="lg:hidden bg-black"></div>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
5
readme.md
Normal file
5
readme.md
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
# v-dashboard ui wasm
|
||||||
|
by rust + dioxus + tailwind
|
||||||
|
|
||||||
|
参考vue项目:
|
||||||
|
https://github.com/wobsoriano/v-dashboard/
|
||||||
109
src/app.rs
Normal file
109
src/app.rs
Normal file
@@ -0,0 +1,109 @@
|
|||||||
|
/*
|
||||||
|
* @Author: plucky
|
||||||
|
* @Date: 2022-10-11 00:07:29
|
||||||
|
* @LastEditTime: 2022-10-15 12:38:33
|
||||||
|
* @Description:
|
||||||
|
*/
|
||||||
|
#![allow(non_snake_case)]
|
||||||
|
|
||||||
|
use dioxus::prelude::*;
|
||||||
|
use crate::{components::*, views::*};
|
||||||
|
|
||||||
|
pub fn app(cx: Scope) -> Element {
|
||||||
|
cx.render(rsx! {
|
||||||
|
Router {
|
||||||
|
self::routes {}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Routes
|
||||||
|
fn routes(cx: Scope) -> Element {
|
||||||
|
cx.render(rsx! {
|
||||||
|
Route { to: "/", login::view{}}
|
||||||
|
Route { to: "/dashboard", Home{} }
|
||||||
|
Route { to: "/ui-elements", Home{} }
|
||||||
|
Route { to: "/tables", Home{} }
|
||||||
|
Route { to: "/forms", Home{} }
|
||||||
|
Route { to: "/cards", Home{} }
|
||||||
|
Route { to: "/modal", Home{} }
|
||||||
|
Route { to: "/blank", Home{} }
|
||||||
|
|
||||||
|
Redirect {from: "", to: "/" }
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Home Page View
|
||||||
|
fn Home(cx: Scope)->Element{
|
||||||
|
let route = use_route(&cx);
|
||||||
|
|
||||||
|
let h = route.last_segment().unwrap_or_default();
|
||||||
|
|
||||||
|
cx.render(rsx!{
|
||||||
|
div {
|
||||||
|
class: "flex h-screen bg-gray-200 font-roboto",
|
||||||
|
sidebar::view{}
|
||||||
|
div {
|
||||||
|
class: "flex-1 flex flex-col overflow-hidden",
|
||||||
|
header::view{}
|
||||||
|
main {
|
||||||
|
class: "flex-1 overflow-x-hidden overflow-y-auto bg-gray-200",
|
||||||
|
div {
|
||||||
|
class: "container mx-auto px-6 py-8",
|
||||||
|
slot {
|
||||||
|
i{"{h}"}
|
||||||
|
match h {
|
||||||
|
"dashboard" => rsx!{ dashboard::view{} },
|
||||||
|
"ui-elements" => rsx!{ ui_elements::view{} },
|
||||||
|
"tables" => rsx!{tables::view{} },
|
||||||
|
"forms" => rsx!{forms::view{} },
|
||||||
|
"cards" => rsx!{card::view{} },
|
||||||
|
"modal" => rsx!{modal::view{} },
|
||||||
|
"blank" => rsx!{blank::view{} },
|
||||||
|
_ => rsx!{ div{}}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// pub fn app2(cx: Scope)->Element{
|
||||||
|
// let show_title = true;
|
||||||
|
// let user_name = Some("bob");
|
||||||
|
// cx.render(rsx!{
|
||||||
|
// div {
|
||||||
|
// class: format_args!("text-2xl font-bold {}", show_title.then(|| "text-red-500").unwrap_or("hidden")),
|
||||||
|
// // Renders nothing by returning None when show_title is false
|
||||||
|
// show_title.then(|| rsx!{
|
||||||
|
// "This is the title"
|
||||||
|
// }),
|
||||||
|
// }
|
||||||
|
|
||||||
|
// div {
|
||||||
|
// // Renders nothing if user_name is None
|
||||||
|
// user_name.map(|name| rsx!("Hello {name}"))
|
||||||
|
// }
|
||||||
|
// })
|
||||||
|
// }
|
||||||
|
|
||||||
|
// router 参数解析
|
||||||
|
// #[derive(Deserialize)]
|
||||||
|
// struct Query { name: String }
|
||||||
|
// // blogpost:post?name=plucky
|
||||||
|
// fn BlogPost(cx: Scope) -> Element {
|
||||||
|
// let post = use_route(&cx).segment("post")?;
|
||||||
|
// let query = use_route(&cx).query::<Query>()?;
|
||||||
|
|
||||||
|
// cx.render(rsx!{
|
||||||
|
// "Viewing post {post}"
|
||||||
|
// "Name selected: {query}"
|
||||||
|
// })
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
185
src/components/header.rs
Normal file
185
src/components/header.rs
Normal file
@@ -0,0 +1,185 @@
|
|||||||
|
use dioxus::{prelude::{*}};
|
||||||
|
use tracing::info;
|
||||||
|
|
||||||
|
use super::sidebar::IS_SIDEBAR_OPEN;
|
||||||
|
|
||||||
|
pub fn view(cx: Scope)->Element{
|
||||||
|
//const dropdownOpen = ref(false);
|
||||||
|
//const { isOpen } = useSidebar();
|
||||||
|
let set_sidebar_open = use_set(&cx,IS_SIDEBAR_OPEN);
|
||||||
|
let dropdown_open = use_state(&cx, || true);
|
||||||
|
|
||||||
|
let dropdown_class = match dropdown_open.get() {
|
||||||
|
true => "transition duration-150 ease-in transform scale-95 opacity-0",
|
||||||
|
false => "transition duration-150 ease-out transform scale-100 opacity-100",
|
||||||
|
};
|
||||||
|
|
||||||
|
cx.render(rsx!{
|
||||||
|
header {
|
||||||
|
class: "flex items-center justify-between px-6 py-4 bg-white border-b-4 border-indigo-600",
|
||||||
|
div {
|
||||||
|
class: "flex items-center",
|
||||||
|
button{
|
||||||
|
class: "text-gray-500 focus:outline-none lg:hidden",//
|
||||||
|
// @click=\"isOpen = true\"\n
|
||||||
|
onclick: move |_| {
|
||||||
|
set_sidebar_open(true);
|
||||||
|
},
|
||||||
|
icons::icon_1{}
|
||||||
|
}
|
||||||
|
|
||||||
|
div {
|
||||||
|
class: "relative mx-4 lg:mx-0",
|
||||||
|
span {
|
||||||
|
class: "absolute inset-y-0 left-0 flex items-center pl-3 ",
|
||||||
|
icons::icon_2{}
|
||||||
|
}
|
||||||
|
input {
|
||||||
|
class: "w-32 pl-10 pr-4 text-indigo-600 border-gray-200 rounded-md sm:w-64 focus:border-indigo-600 focus:ring focus:ring-opacity-40 focus:ring-indigo-500",
|
||||||
|
placeholder: "Search",
|
||||||
|
r#type: "text",
|
||||||
|
value: "",
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
div {
|
||||||
|
class: "flex items-center",
|
||||||
|
button {
|
||||||
|
class: "flex mx-4 text-gray-600 focus:outline-none",
|
||||||
|
icons::icon_3{}
|
||||||
|
}
|
||||||
|
|
||||||
|
div {
|
||||||
|
class: "relative",
|
||||||
|
button{
|
||||||
|
class: "relative z-10 block w-8 h-8 overflow-hidden rounded-full shadow focus:outline-none",
|
||||||
|
// @click=\"dropdownOpen = !dropdownOpen\"\n
|
||||||
|
onclick: move |_| {
|
||||||
|
dropdown_open.set(!dropdown_open);
|
||||||
|
},
|
||||||
|
img {
|
||||||
|
class: "object-cover w-full h-full",
|
||||||
|
alt: "Your avatar",
|
||||||
|
src: "https://images.unsplash.com/photo-1528892952291-009c663ce843?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=296&q=80",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
div{
|
||||||
|
class:"fixed inset-0 z-10 w-full h-full",//
|
||||||
|
// v-show: "dropdownOpen",
|
||||||
|
//@click=\"dropdownOpen = false\"
|
||||||
|
// 点击屏幕关闭菜单
|
||||||
|
hidden: "{dropdown_open}",
|
||||||
|
onclick: move |_| {
|
||||||
|
dropdown_open.set(true);
|
||||||
|
},
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// <transition
|
||||||
|
// enter-active-class="transition duration-150 ease-out transform"
|
||||||
|
// enter-from-class="scale-95 opacity-0"
|
||||||
|
// enter-to-class="scale-100 opacity-100"
|
||||||
|
// leave-active-class="transition duration-150 ease-in transform"
|
||||||
|
// leave-from-class="scale-100 opacity-100"
|
||||||
|
// leave-to-class="scale-95 opacity-0"
|
||||||
|
// >
|
||||||
|
|
||||||
|
div{
|
||||||
|
class:"absolute right-0 z-20 w-48 py-2 mt-2 bg-white rounded-md shadow-xl {dropdown_class}",
|
||||||
|
// v-show: "dropdownOpen",
|
||||||
|
hidden: "{dropdown_open}",
|
||||||
|
//onmouseout onmouseover
|
||||||
|
onmouseout: move |_| {
|
||||||
|
info!("onmouseout");
|
||||||
|
},
|
||||||
|
// style: "display:block",
|
||||||
|
|
||||||
|
a{
|
||||||
|
class:"block px-4 py-2 text-sm text-gray-700 hover:bg-indigo-600 hover:text-white",
|
||||||
|
href:"#",
|
||||||
|
"Profile"
|
||||||
|
}
|
||||||
|
a{
|
||||||
|
class:"block px-4 py-2 text-sm text-gray-700 hover:bg-indigo-600 hover:text-white",
|
||||||
|
href:"#",
|
||||||
|
"Products"
|
||||||
|
}
|
||||||
|
|
||||||
|
a{
|
||||||
|
class:"block px-4 py-2 text-sm text-gray-700 hover:bg-indigo-600 hover:text-white",
|
||||||
|
href:"/",
|
||||||
|
"Log out"
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// </transition>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
mod icons{
|
||||||
|
use dioxus::prelude::*;
|
||||||
|
|
||||||
|
pub fn icon_1(cx: Scope)->Element{
|
||||||
|
cx.render(rsx!{
|
||||||
|
svg{
|
||||||
|
class:"w-6 h-6",
|
||||||
|
view_box:"0 0 24 24",
|
||||||
|
fill:"none",
|
||||||
|
xmlns:"http://www.w3.org/2000/svg",
|
||||||
|
path{
|
||||||
|
d:"M4 6H20M4 12H20M4 18H11",
|
||||||
|
stroke:"currentColor",
|
||||||
|
stroke_width:"2",
|
||||||
|
stroke_linecap:"round",
|
||||||
|
stroke_linejoin:"round",
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn icon_2(cx: Scope)->Element{
|
||||||
|
cx.render(rsx!{
|
||||||
|
svg{
|
||||||
|
class:"w-5 h-5 text-gray-500",
|
||||||
|
view_box:"0 0 24 24",
|
||||||
|
fill:"none",
|
||||||
|
xmlns:"http://www.w3.org/2000/svg",
|
||||||
|
path{
|
||||||
|
d:"M21 21L15 15M17 10C17 13.866 13.866 17 10 17C6.13401 17 3 13.866 3 10C3 6.13401 6.13401 3 10 3C13.866 3 17 6.13401 17 10Z",
|
||||||
|
stroke:"currentColor",
|
||||||
|
stroke_width:"2",
|
||||||
|
stroke_linecap:"round",
|
||||||
|
stroke_linejoin:"round",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn icon_3(cx: Scope)->Element{
|
||||||
|
cx.render(rsx!{
|
||||||
|
svg{
|
||||||
|
class:"w-6 h-6",
|
||||||
|
view_box:"0 0 24 24",
|
||||||
|
fill:"none",
|
||||||
|
xmlns:"http://www.w3.org/2000/svg",
|
||||||
|
path{
|
||||||
|
d:"M15 17H20L18.5951 15.5951C18.2141 15.2141 18 14.6973 18 14.1585V11C18 8.38757 16.3304 6.16509 14 5.34142V5C14 3.89543 13.1046 3 12 3C10.8954 3 10 3.89543 10 5V5.34142C7.66962 6.16509 6 8.38757 6 11V14.1585C6 14.6973 5.78595 15.2141 5.40493 15.5951L4 17H9M15 17V18C15 19.6569 13.6569 21 12 21C10.3431 21 9 19.6569 9 18V17M15 17H9",
|
||||||
|
stroke:"currentColor",
|
||||||
|
stroke_width:"2",
|
||||||
|
stroke_linecap:"round",
|
||||||
|
stroke_linejoin:"round",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
20
src/components/mod.rs
Normal file
20
src/components/mod.rs
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
/*
|
||||||
|
* @Author: plucky
|
||||||
|
* @Date: 2022-10-11 23:13:17
|
||||||
|
* @LastEditTime: 2022-10-14 12:33:51
|
||||||
|
* @Description:
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
pub mod header;
|
||||||
|
pub mod sidebar;
|
||||||
|
|
||||||
|
|
||||||
|
// pub fn view(cx: Scope)->Element{
|
||||||
|
|
||||||
|
// cx.render(rsx!{
|
||||||
|
// div {
|
||||||
|
// }
|
||||||
|
// })
|
||||||
|
// }
|
||||||
267
src/components/sidebar.rs
Normal file
267
src/components/sidebar.rs
Normal file
@@ -0,0 +1,267 @@
|
|||||||
|
/*
|
||||||
|
* @Author: plucky
|
||||||
|
* @Date: 2022-10-11 18:53:17
|
||||||
|
* @LastEditTime: 2022-10-15 14:17:49
|
||||||
|
* @Description:
|
||||||
|
*/
|
||||||
|
|
||||||
|
use dioxus::{prelude::{*}};
|
||||||
|
use dioxus::prelude::Atom;
|
||||||
|
|
||||||
|
pub static IS_SIDEBAR_OPEN: Atom<bool> = |_| false;
|
||||||
|
|
||||||
|
pub fn view(cx:Scope)->Element{
|
||||||
|
let route = use_route(&cx);
|
||||||
|
let route_name = route.last_segment().unwrap_or_default();
|
||||||
|
|
||||||
|
let set_sidebar_open = use_set(&cx,IS_SIDEBAR_OPEN);
|
||||||
|
let is_open = use_read(&cx,IS_SIDEBAR_OPEN);
|
||||||
|
|
||||||
|
let highlight_class = |e:&str|{
|
||||||
|
match e == route_name {
|
||||||
|
true => "flex items-center px-6 py-2 mt-4 duration-200 border-l-4 bg-gray-600 bg-opacity-25 text-gray-100 border-gray-100",
|
||||||
|
false => "flex items-center px-6 py-2 mt-4 duration-200 border-l-4 border-gray-900 text-gray-500 hover:bg-gray-600 hover:bg-opacity-25 hover:text-gray-100",
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
cx.render(rsx!(
|
||||||
|
div{
|
||||||
|
class:"flex",
|
||||||
|
div{
|
||||||
|
// :class="isOpen ? 'block' : 'hidden'"
|
||||||
|
// @click="isOpen = false"
|
||||||
|
onclick: move |_| {
|
||||||
|
set_sidebar_open(false);
|
||||||
|
},
|
||||||
|
// class:"fixed inset-0 z-20 transition-opacity bg-black opacity-50 lg:hidden",
|
||||||
|
class: format_args!("fixed inset-0 z-20 transition-opacity bg-black opacity-50 lg:hidden {}",if *is_open {"block"} else {"hidden"}),
|
||||||
|
// hidden: format_args!("{}",!is_open),
|
||||||
|
|
||||||
|
}
|
||||||
|
div{
|
||||||
|
// :class="isOpen ? 'translate-x-0 ease-out' : '-translate-x-full ease-in'"
|
||||||
|
// class:"fixed inset-y-0 left-0 z-30 w-64 overflow-y-auto transition duration-300 transform bg-gray-900 lg:translate-x-0 lg:static lg:inset-0",
|
||||||
|
class: format_args!("fixed inset-y-0 left-0 z-30 w-64 overflow-y-auto transition duration-300 transform bg-gray-900 lg:translate-x-0 lg:static lg:inset-0 {}",
|
||||||
|
if !*is_open { "-translate-x-full ease-in" } else { "translate-x-0 ease-out" }),
|
||||||
|
div {
|
||||||
|
class: "flex items-center justify-center mt-8 ",
|
||||||
|
div {
|
||||||
|
class: "flex items-center",
|
||||||
|
icons::icon_1 {}
|
||||||
|
span {
|
||||||
|
class: "mx-2 text-2xl font-semibold text-white",
|
||||||
|
"Dashboard"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
nav{
|
||||||
|
class: "mt-10",
|
||||||
|
// router-link
|
||||||
|
Link{
|
||||||
|
class: highlight_class
|
||||||
|
("dashboard"),
|
||||||
|
//to="/dashboard"
|
||||||
|
to: "/dashboard",
|
||||||
|
icons::icon_2 {}
|
||||||
|
span{class:"mx-4","Dashboard"}
|
||||||
|
}
|
||||||
|
Link{
|
||||||
|
class: highlight_class
|
||||||
|
("ui-elements"),
|
||||||
|
to: "/ui-elements",
|
||||||
|
icons::icon_3 {}
|
||||||
|
span{class:"mx-4","UI Elements"}
|
||||||
|
}
|
||||||
|
Link{
|
||||||
|
class: highlight_class
|
||||||
|
("tables"),
|
||||||
|
to: "/tables",
|
||||||
|
icons::icon_4 {}
|
||||||
|
span{class:"mx-4","Tables"}
|
||||||
|
}
|
||||||
|
Link{
|
||||||
|
class: highlight_class
|
||||||
|
("forms"),
|
||||||
|
to: "/forms",
|
||||||
|
icons::icon_5 {}
|
||||||
|
span{class:"mx-4","Forms"}
|
||||||
|
}
|
||||||
|
Link{
|
||||||
|
class: highlight_class
|
||||||
|
("cards"),
|
||||||
|
to: "/cards",
|
||||||
|
icons::icon_6 {}
|
||||||
|
span{class:"mx-4","Cards"}
|
||||||
|
}
|
||||||
|
Link{
|
||||||
|
class: highlight_class
|
||||||
|
("modal"),
|
||||||
|
to: "/modal",
|
||||||
|
icons::icon_7 {}
|
||||||
|
span{class:"mx-4","Modal"}
|
||||||
|
}
|
||||||
|
|
||||||
|
Link{
|
||||||
|
class: highlight_class
|
||||||
|
("blank"),
|
||||||
|
to: "/blank",
|
||||||
|
icons::icon_8 {}
|
||||||
|
span{class:"mx-4","Blank"}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
))
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
mod icons{
|
||||||
|
use dioxus::prelude::*;
|
||||||
|
use dioxus_html_macro::html;
|
||||||
|
|
||||||
|
pub fn icon_1(cx: Scope)->Element{
|
||||||
|
cx.render(html!{
|
||||||
|
<svg
|
||||||
|
class="w-12 h-12"
|
||||||
|
view_box="0 0 512 512"
|
||||||
|
fill="none"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M364.61 390.213C304.625 450.196 207.37 450.196 147.386 390.213C117.394 360.22 102.398 320.911 102.398 281.6C102.398 242.291 117.394 202.981 147.386 172.989C147.386 230.4 153.6 281.6 230.4 307.2C230.4 256 256 102.4 294.4 76.7999C320 128 334.618 142.997 364.608 172.989C394.601 202.981 409.597 242.291 409.597 281.6C409.597 320.911 394.601 360.22 364.61 390.213Z"
|
||||||
|
fill="#4C51BF"
|
||||||
|
stroke="#4C51BF"
|
||||||
|
stroke_width="2"
|
||||||
|
stroke_linecap="round"
|
||||||
|
stroke_linejoin="round"
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
d="M201.694 387.105C231.686 417.098 280.312 417.098 310.305 387.105C325.301 372.109 332.8 352.456 332.8 332.8C332.8 313.144 325.301 293.491 310.305 278.495C295.309 263.498 288 256 275.2 230.4C256 243.2 243.201 320 243.201 345.6C201.694 345.6 179.2 332.8 179.2 332.8C179.2 352.456 186.698 372.109 201.694 387.105Z"
|
||||||
|
fill="white"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
})
|
||||||
|
}
|
||||||
|
pub fn icon_2(cx:Scope)->Element{
|
||||||
|
cx.render(html!{
|
||||||
|
<svg
|
||||||
|
class="w-5 h-5"
|
||||||
|
view_box="0 0 20 20"
|
||||||
|
fill="none"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M2 10C2 5.58172 5.58172 2 10 2V10H18C18 14.4183 14.4183 18 10 18C5.58172 18 2 14.4183 2 10Z"
|
||||||
|
fill="currentColor"
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
d="M12 2.25195C14.8113 2.97552 17.0245 5.18877 17.748 8.00004H12V2.25195Z"
|
||||||
|
fill="currentColor"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn icon_3(cx:Scope)->Element{
|
||||||
|
cx.render(html!(
|
||||||
|
<svg
|
||||||
|
class="w-5 h-5"
|
||||||
|
view_box="0 0 20 20"
|
||||||
|
fill="none"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M5 3C3.89543 3 3 3.89543 3 5V7C3 8.10457 3.89543 9 5 9H7C8.10457 9 9 8.10457 9 7V5C9 3.89543 8.10457 3 7 3H5Z"
|
||||||
|
fill="currentColor"
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
d="M5 11C3.89543 11 3 11.8954 3 13V15C3 16.1046 3.89543 17 5 17H7C8.10457 17 9 16.1046 9 15V13C9 11.8954 8.10457 11 7 11H5Z"
|
||||||
|
fill="currentColor"
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
d="M11 5C11 3.89543 11.8954 3 13 3H15C16.1046 3 17 3.89543 17 5V7C17 8.10457 16.1046 9 15 9H13C11.8954 9 11 8.10457 11 7V5Z"
|
||||||
|
fill="currentColor"
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
d="M11 13C11 11.8954 11.8954 11 13 11H15C16.1046 11 17 11.8954 17 13V15C17 16.1046 16.1046 17 15 17H13C11.8954 17 11 16.1046 11 15V13Z"
|
||||||
|
fill="currentColor"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn icon_4(cx:Scope)->Element{
|
||||||
|
cx.render(html!(
|
||||||
|
<svg
|
||||||
|
class="w-5 h-5"
|
||||||
|
view_box="0 0 20 20"
|
||||||
|
fill="none"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M7 3C6.44772 3 6 3.44772 6 4C6 4.55228 6.44772 5 7 5H13C13.5523 5 14 4.55228 14 4C14 3.44772 13.5523 3 13 3H7Z"
|
||||||
|
fill="currentColor"
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
d="M4 7C4 6.44772 4.44772 6 5 6H15C15.5523 6 16 6.44772 16 7C16 7.55228 15.5523 8 15 8H5C4.44772 8 4 7.55228 4 7Z"
|
||||||
|
fill="currentColor"
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
d="M2 11C2 9.89543 2.89543 9 4 9H16C17.1046 9 18 9.89543 18 11V15C18 16.1046 17.1046 17 16 17H4C2.89543 17 2 16.1046 2 15V11Z"
|
||||||
|
fill="currentColor"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn icon_5(cx:Scope)->Element{
|
||||||
|
cx.render(html!(
|
||||||
|
<svg class="w-5 h-5" fill="currentColor" view_box="0 0 20 20">
|
||||||
|
<path
|
||||||
|
d="M17.414 2.586a2 2 0 00-2.828 0L7 10.172V13h2.828l7.586-7.586a2 2 0 000-2.828z"
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
fill_rule="evenodd"
|
||||||
|
d="M2 6a2 2 0 012-2h4a1 1 0 010 2H4v10h10v-4a1 1 0 112 0v4a2 2 0 01-2 2H4a2 2 0 01-2-2V6z"
|
||||||
|
clip_rule="evenodd"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn icon_6(cx:Scope)->Element{
|
||||||
|
cx.render(html!(
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" class="w-5 h-5" view_box="0 0 20 20" fill="currentColor">
|
||||||
|
<path d="M4 4a2 2 0 00-2 2v1h16V6a2 2 0 00-2-2H4z" />
|
||||||
|
<path fill_rule="evenodd" d="M18 9H2v5a2 2 0 002 2h12a2 2 0 002-2V9zM4 13a1 1 0 011-1h1a1 1 0 110 2H5a1 1 0 01-1-1zm5-1a1 1 0 100 2h1a1 1 0 100-2H9z"
|
||||||
|
clip_rule="evenodd" />
|
||||||
|
</svg>
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn icon_7(cx:Scope)->Element{
|
||||||
|
cx.render(html!(
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" class="w-5 h-5" view_box="0 0 20 20" fill="currentColor">
|
||||||
|
<path d="M3 12v3c0 1.657 3.134 3 7 3s7-1.343 7-3v-3c0 1.657-3.134 3-7 3s-7-1.343-7-3z" />
|
||||||
|
<path d="M3 7v3c0 1.657 3.134 3 7 3s7-1.343 7-3V7c0 1.657-3.134 3-7 3S3 8.657 3 7z" />
|
||||||
|
<path d="M17 5c0 1.657-3.134 3-7 3S3 6.657 3 5s3.134-3 7-3 7 1.343 7 3z" />
|
||||||
|
</svg>
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn icon_8(cx:Scope)->Element{
|
||||||
|
cx.render(html!(
|
||||||
|
<svg class="w-5 h-5" fill="currentColor" view_box="0 0 20 20">
|
||||||
|
<path
|
||||||
|
d="M3 4a1 1 0 011-1h12a1 1 0 011 1v2a1 1 0 01-1 1H4a1 1 0 01-1-1V4zM3 10a1 1 0 011-1h6a1 1 0 011 1v6a1 1 0 01-1 1H4a1 1 0 01-1-1v-6zM14 9a1 1 0 00-1 1v6a1 1 0 001 1h2a1 1 0 001-1v-6a1 1 0 00-1-1h-2z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
12
src/lib.rs
Normal file
12
src/lib.rs
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
/*
|
||||||
|
* @Author: plucky
|
||||||
|
* @Date: 2022-10-11 00:07:45
|
||||||
|
* @LastEditTime: 2022-10-14 16:52:30
|
||||||
|
* @Description:
|
||||||
|
*/
|
||||||
|
|
||||||
|
pub mod app;
|
||||||
|
pub mod components;
|
||||||
|
pub mod views;
|
||||||
|
pub mod modules;
|
||||||
|
|
||||||
16
src/main.rs
Normal file
16
src/main.rs
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
/*
|
||||||
|
* @Author: plucky
|
||||||
|
* @Date: 2022-10-10 23:58:17
|
||||||
|
* @LastEditTime: 2022-10-15 14:02:24
|
||||||
|
* @Description:
|
||||||
|
*/
|
||||||
|
|
||||||
|
use r_dashboard::app::*;
|
||||||
|
|
||||||
|
|
||||||
|
// trunk serve
|
||||||
|
fn main() {
|
||||||
|
console_error_panic_hook::set_once();
|
||||||
|
tracing_wasm::set_as_global_default();
|
||||||
|
dioxus::web::launch(app);
|
||||||
|
}
|
||||||
82
src/modules/demo_data.rs
Normal file
82
src/modules/demo_data.rs
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
/*
|
||||||
|
* @Author: plucky
|
||||||
|
* @Date: 2022-10-14 18:11:55
|
||||||
|
* @LastEditTime: 2022-10-14 23:48:07
|
||||||
|
* @Description:
|
||||||
|
*/
|
||||||
|
|
||||||
|
use dioxus::prelude::Atom;
|
||||||
|
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
|
||||||
|
pub struct UseTableData{
|
||||||
|
pub simpleTableData: Vec<SimpleTableData>,
|
||||||
|
pub paginatedTableData: Vec<PaginatedTableData>,
|
||||||
|
pub wideTableData: Vec<WideTableData>,
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 表格测试数据 for tables
|
||||||
|
pub static USE_TABLE_DATA: Atom<UseTableData> = |_| {
|
||||||
|
UseTableData{
|
||||||
|
simpleTableData: vec![
|
||||||
|
SimpleTableData{
|
||||||
|
city: "New York".to_string(),
|
||||||
|
totalOrders: "200,120".to_string(),
|
||||||
|
},
|
||||||
|
SimpleTableData{
|
||||||
|
city: "Manchester".to_string(),
|
||||||
|
totalOrders: "632,310".to_string(),
|
||||||
|
},
|
||||||
|
SimpleTableData{
|
||||||
|
city: "London".to_string(),
|
||||||
|
totalOrders: "1,200,120".to_string(),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
paginatedTableData: vec![
|
||||||
|
PaginatedTableData{
|
||||||
|
picture: "https://images.unsplash.com/photo-1494790108377-be9c29b29330?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2.2&w=160&h=160&q=80".to_string(),
|
||||||
|
name: "Vera Carpenter".to_string(),
|
||||||
|
role: "Admin".to_string(),
|
||||||
|
created: "Jan 21, 2020".to_string(),
|
||||||
|
status: "Active".to_string(),
|
||||||
|
statusColor: "green".to_string(),
|
||||||
|
},
|
||||||
|
PaginatedTableData{
|
||||||
|
picture: "https://images.unsplash.com/photo-1500648767791-00dcc994a43e?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2.2&w=160&h=160&q=80".to_string(),
|
||||||
|
name: "Blake Bowman".to_string(),
|
||||||
|
role: "Editor".to_string(),
|
||||||
|
created: "Jan 01, 2020".to_string(),
|
||||||
|
status: "Active".to_string(),
|
||||||
|
statusColor: "green".to_string(),
|
||||||
|
},
|
||||||
|
PaginatedTableData{
|
||||||
|
picture: "https://images.unsplash.com/photo-1540845511934-7721dd7adec3?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2.2&w=160&h=160&q=80".to_string(),
|
||||||
|
name: "Dana Moore".to_string(),
|
||||||
|
role: "Editor".to_string(),
|
||||||
|
created: "Jan 10, 2020".to_string(),
|
||||||
|
status: "Suspended".to_string(),
|
||||||
|
statusColor: "orange".to_string(),
|
||||||
|
},
|
||||||
|
PaginatedTableData{
|
||||||
|
picture: "https://images.unsplash.com/photo-1522609925277-66fea332c575?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2.2&h=160&w=160&q=80".to_string(),
|
||||||
|
name: "Alonzo Cox".to_string(),
|
||||||
|
role: "Admin".to_string(),
|
||||||
|
created: "Jan 18, 2020".to_string(),
|
||||||
|
status: "Inactive".to_string(),
|
||||||
|
statusColor: "red".to_string(),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
wideTableData: (0..5).map(|_i| {
|
||||||
|
WideTableData {
|
||||||
|
name: "John Doe".into(),
|
||||||
|
email: "john@example.com".into(),
|
||||||
|
title: "Software Engineer".into(),
|
||||||
|
title2: "Web dev".into(),
|
||||||
|
status: "Active".into(),
|
||||||
|
role: "Owner".into(),
|
||||||
|
}
|
||||||
|
}).collect(),
|
||||||
|
}
|
||||||
|
};
|
||||||
40
src/modules/mod.rs
Normal file
40
src/modules/mod.rs
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
#![allow(non_snake_case)]
|
||||||
|
|
||||||
|
pub mod demo_data;
|
||||||
|
|
||||||
|
/// USERS for dashboard
|
||||||
|
#[derive(Debug )]
|
||||||
|
pub struct User {
|
||||||
|
pub name: String,
|
||||||
|
pub email: String,
|
||||||
|
pub title: String,
|
||||||
|
pub title2: String,
|
||||||
|
pub status: String,
|
||||||
|
pub role: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// simple data for talbes
|
||||||
|
pub struct SimpleTableData {
|
||||||
|
pub city: String,
|
||||||
|
pub totalOrders: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
pub struct PaginatedTableData {
|
||||||
|
pub picture: String,
|
||||||
|
pub name: String,
|
||||||
|
pub role: String,
|
||||||
|
pub created: String,
|
||||||
|
pub status: String,
|
||||||
|
pub statusColor: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
pub struct WideTableData {
|
||||||
|
pub name: String,
|
||||||
|
pub email: String,
|
||||||
|
pub title: String,
|
||||||
|
pub title2: String,
|
||||||
|
pub status: String,
|
||||||
|
pub role: String,
|
||||||
|
}
|
||||||
17
src/views/blank.rs
Normal file
17
src/views/blank.rs
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
/*
|
||||||
|
* @Author: plucky
|
||||||
|
* @Date: 2022-10-15 09:52:33
|
||||||
|
* @LastEditTime: 2022-10-15 09:58:23
|
||||||
|
* @Description:
|
||||||
|
*/
|
||||||
|
|
||||||
|
use dioxus::prelude::*;
|
||||||
|
use dioxus_html_macro::html;
|
||||||
|
|
||||||
|
pub fn view(cx: Scope)->Element{
|
||||||
|
|
||||||
|
cx.render(html!{
|
||||||
|
<h3 class="text-gray-700 text-3xl font-medium">"Blank Page"</h3>
|
||||||
|
|
||||||
|
})
|
||||||
|
}
|
||||||
137
src/views/card.rs
Normal file
137
src/views/card.rs
Normal file
@@ -0,0 +1,137 @@
|
|||||||
|
/*
|
||||||
|
* @Author: plucky
|
||||||
|
* @Date: 2022-10-15 09:47:37
|
||||||
|
* @LastEditTime: 2022-10-15 09:51:33
|
||||||
|
* @Description:
|
||||||
|
*/
|
||||||
|
use dioxus::prelude::*;
|
||||||
|
|
||||||
|
pub fn view(cx: Scope)->Element{
|
||||||
|
|
||||||
|
cx.render(rsx!{
|
||||||
|
div {
|
||||||
|
h3 {
|
||||||
|
class: "text-3xl font-semibold text-gray-700",
|
||||||
|
"Card"
|
||||||
|
}
|
||||||
|
div {
|
||||||
|
class: "mt-4 mb-3",
|
||||||
|
h4 {
|
||||||
|
class: "text-gray-700",
|
||||||
|
"Stacked"
|
||||||
|
}
|
||||||
|
div {
|
||||||
|
class: "max-w-sm mt-6 overflow-hidden bg-white rounded shadow-lg",
|
||||||
|
img {
|
||||||
|
class: "w-full",
|
||||||
|
alt: "Sunset in the mountains",
|
||||||
|
src: "https://picsum.photos/id/1016/384/234",
|
||||||
|
}
|
||||||
|
div {
|
||||||
|
class: "px-6 py-4",
|
||||||
|
div {
|
||||||
|
class: "mb-2 text-xl font-bold text-gray-900",
|
||||||
|
"The Coldest Sunset"
|
||||||
|
}
|
||||||
|
p {
|
||||||
|
class: "text-base text-gray-700",
|
||||||
|
"Lorem ipsum dolor sit amet, consectetur adipisicing elit.\n Voluptatibus quia, nulla! Maiores et perferendis eaque,\n exercitationem praesentium nihil."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
div {
|
||||||
|
class: "px-6 pt-4 pb-2",
|
||||||
|
span {
|
||||||
|
class: "inline-block px-3 py-1 mb-2 mr-2 text-sm font-semibold text-gray-700 bg-gray-200 rounded-full",
|
||||||
|
"#photography"
|
||||||
|
}
|
||||||
|
span {
|
||||||
|
class: "inline-block px-3 py-1 mb-2 mr-2 text-sm font-semibold text-gray-700 bg-gray-200 rounded-full",
|
||||||
|
"#travel"
|
||||||
|
}
|
||||||
|
span {
|
||||||
|
class: "inline-block px-3 py-1 mb-2 mr-2 text-sm font-semibold text-gray-700 bg-gray-200 rounded-full",
|
||||||
|
"#winter"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
hr {
|
||||||
|
|
||||||
|
}
|
||||||
|
div {
|
||||||
|
class: "mt-5",
|
||||||
|
h4 {
|
||||||
|
class: "text-gray-700",
|
||||||
|
"Horizontal"
|
||||||
|
}
|
||||||
|
div {
|
||||||
|
class: "w-full max-w-sm mt-6 lg:max-w-full lg:flex",
|
||||||
|
div {
|
||||||
|
class: "flex-none h-48 overflow-hidden text-center bg-cover rounded-t lg:h-auto lg:w-48 lg:rounded-t-none lg:rounded-l",
|
||||||
|
style: "background-image: url('https://picsum.photos/id/0/192/213')",
|
||||||
|
title: "Woman holding a mug",
|
||||||
|
}
|
||||||
|
div {
|
||||||
|
class: "flex flex-col justify-between p-4 leading-normal bg-white border-b border-l border-r border-gray-200 rounded-b lg:border-l-0 lg:border-t lg:border-gray-200 lg:rounded-b-none lg:rounded-r",
|
||||||
|
div {
|
||||||
|
class: "mb-8",
|
||||||
|
p {
|
||||||
|
class: "flex items-center text-sm text-gray-600",
|
||||||
|
icons::icon_1 {}
|
||||||
|
"Members only"
|
||||||
|
}
|
||||||
|
div {
|
||||||
|
class: "mb-2 text-xl font-bold text-gray-900",
|
||||||
|
"Can coffee make you a better developer?"
|
||||||
|
}
|
||||||
|
p {
|
||||||
|
class: "text-base text-gray-700",
|
||||||
|
"Lorem ipsum dolor sit amet, consectetur adipisicing elit.\n Voluptatibus quia, nulla! Maiores et perferendis eaque,\n exercitationem praesentium nihil."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
div {
|
||||||
|
class: "flex items-center",
|
||||||
|
img {
|
||||||
|
class: "w-10 h-10 mr-4 rounded-full",
|
||||||
|
alt: "Avatar of Jonathan Reinink",
|
||||||
|
src: "https://via.placeholder.com/50",
|
||||||
|
}
|
||||||
|
div {
|
||||||
|
class: "text-sm",
|
||||||
|
p {
|
||||||
|
class: "leading-none text-gray-900",
|
||||||
|
"Jonathan Reinink"
|
||||||
|
}
|
||||||
|
p {
|
||||||
|
class: "text-gray-600",
|
||||||
|
"Aug 18"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
mod icons{
|
||||||
|
use dioxus::prelude::*;
|
||||||
|
use dioxus_html_macro::html;
|
||||||
|
|
||||||
|
pub fn icon_1(cx: Scope)->Element{
|
||||||
|
cx.render(html!{
|
||||||
|
<svg
|
||||||
|
class="w-3 h-3 mr-2 text-gray-500 fill-current"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
view_box="0 0 20 20"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M4 8V6a6 6 0 1 1 12 0v2h1a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2H3a2 2 0 0 1-2-2v-8c0-1.1.9-2 2-2h1zm5 6.73V17h2v-2.27a2 2 0 1 0-2 0zM7 6v2h6V6a3 3 0 0 0-6 0z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
318
src/views/dashboard.rs
Normal file
318
src/views/dashboard.rs
Normal file
@@ -0,0 +1,318 @@
|
|||||||
|
/*
|
||||||
|
* @Author: plucky
|
||||||
|
* @Date: 2022-10-14 12:31:43
|
||||||
|
* @LastEditTime: 2022-10-14 23:48:22
|
||||||
|
* @Description:
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
use dioxus::prelude::*;
|
||||||
|
|
||||||
|
use crate::modules::User;
|
||||||
|
|
||||||
|
// test data
|
||||||
|
pub static USERS: Atom<Vec<User>> = |_| {
|
||||||
|
(0..5).map(|_i| {
|
||||||
|
User {
|
||||||
|
name: "John Doe".into(),
|
||||||
|
email: "john@example.com".into(),
|
||||||
|
title: "Software Engineer".into(),
|
||||||
|
title2: "Web dev".into(),
|
||||||
|
status: "Active".into(),
|
||||||
|
role: "Owner".into(),
|
||||||
|
}
|
||||||
|
}).collect()
|
||||||
|
};
|
||||||
|
|
||||||
|
pub fn view(cx: Scope)->Element{
|
||||||
|
let users = use_read(&cx, USERS);
|
||||||
|
|
||||||
|
cx.render(rsx!{
|
||||||
|
div {
|
||||||
|
h3 {
|
||||||
|
class: "text-3xl font-medium text-gray-700",
|
||||||
|
"Dashboard"
|
||||||
|
}
|
||||||
|
div {
|
||||||
|
class: "mt-4",
|
||||||
|
div {
|
||||||
|
class: "flex flex-wrap -mx-6",
|
||||||
|
div {
|
||||||
|
class: "w-full px-6 sm:w-1/2 xl:w-1/3",
|
||||||
|
div {
|
||||||
|
class: "flex items-center px-5 py-6 bg-white rounded-md shadow-sm",
|
||||||
|
div {
|
||||||
|
class: "p-3 bg-indigo-600 bg-opacity-75 rounded-full",
|
||||||
|
icons::icon_1 {}
|
||||||
|
}
|
||||||
|
div {
|
||||||
|
class: "mx-5",
|
||||||
|
h4 {
|
||||||
|
class: "text-2xl font-semibold text-gray-700",
|
||||||
|
"8,282"
|
||||||
|
}
|
||||||
|
div {
|
||||||
|
class: "text-gray-500",
|
||||||
|
"New Users"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
div {
|
||||||
|
class: "w-full px-6 mt-6 sm:w-1/2 xl:w-1/3 sm:mt-0",
|
||||||
|
div {
|
||||||
|
class: "flex items-center px-5 py-6 bg-white rounded-md shadow-sm",
|
||||||
|
div {
|
||||||
|
class: "p-3 bg-blue-600 bg-opacity-75 rounded-full",
|
||||||
|
icons::icon_2 {}
|
||||||
|
}
|
||||||
|
div {
|
||||||
|
class: "mx-5",
|
||||||
|
h4 {
|
||||||
|
class: "text-2xl font-semibold text-gray-700",
|
||||||
|
"200,521"
|
||||||
|
}
|
||||||
|
div {
|
||||||
|
class: "text-gray-500",
|
||||||
|
"Total Orders"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
div {
|
||||||
|
class: "w-full px-6 mt-6 sm:w-1/2 xl:w-1/3 xl:mt-0",
|
||||||
|
div {
|
||||||
|
class: "flex items-center px-5 py-6 bg-white rounded-md shadow-sm",
|
||||||
|
div {
|
||||||
|
class: "p-3 bg-pink-600 bg-opacity-75 rounded-full",
|
||||||
|
icons::icon_3 {}
|
||||||
|
}
|
||||||
|
div {
|
||||||
|
class: "mx-5",
|
||||||
|
h4 {
|
||||||
|
class: "text-2xl font-semibold text-gray-700",
|
||||||
|
"215,542"
|
||||||
|
}
|
||||||
|
div {
|
||||||
|
class: "text-gray-500",
|
||||||
|
"Available Products"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
div {
|
||||||
|
class: "mt-8",
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
div {
|
||||||
|
class: "flex flex-col mt-8",
|
||||||
|
div {
|
||||||
|
class: "py-2 -my-2 overflow-x-auto sm:-mx-6 sm:px-6 lg:-mx-8 lg:px-8",
|
||||||
|
div {
|
||||||
|
class: "inline-block min-w-full overflow-hidden align-middle border-b border-gray-200 shadow sm:rounded-lg",
|
||||||
|
table {
|
||||||
|
class: "min-w-full",
|
||||||
|
thead {
|
||||||
|
tr {
|
||||||
|
th {
|
||||||
|
class: "px-6 py-3 text-xs font-medium leading-4 tracking-wider text-left text-gray-500 uppercase border-b border-gray-200 bg-gray-50",
|
||||||
|
"Name"
|
||||||
|
}
|
||||||
|
th {
|
||||||
|
class: "px-6 py-3 text-xs font-medium leading-4 tracking-wider text-left text-gray-500 uppercase border-b border-gray-200 bg-gray-50",
|
||||||
|
"Title"
|
||||||
|
}
|
||||||
|
th {
|
||||||
|
class: "px-6 py-3 text-xs font-medium leading-4 tracking-wider text-left text-gray-500 uppercase border-b border-gray-200 bg-gray-50",
|
||||||
|
"Status"
|
||||||
|
}
|
||||||
|
th {
|
||||||
|
class: "px-6 py-3 text-xs font-medium leading-4 tracking-wider text-left text-gray-500 uppercase border-b border-gray-200 bg-gray-50",
|
||||||
|
"Role"
|
||||||
|
}
|
||||||
|
th {
|
||||||
|
class: "px-6 py-3 border-b border-gray-200 bg-gray-50",
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 表格数据
|
||||||
|
tbody {
|
||||||
|
class: "bg-white",
|
||||||
|
// "<tr v-for=\"(u, index) in users\" :key=\"index\">"
|
||||||
|
users.iter().map(|u|{
|
||||||
|
rsx!{ UserList{user:u}}
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// #[derive(PartialEq, Props)]
|
||||||
|
// pub struct UserListProps<'a>{
|
||||||
|
// user: &'a User,
|
||||||
|
// }
|
||||||
|
|
||||||
|
#[allow(non_snake_case)]
|
||||||
|
#[inline_props]
|
||||||
|
pub fn UserList<'a>(cx: Scope<UserListProps>, user: &'a User) -> Element {
|
||||||
|
// let u = cx.props.user;
|
||||||
|
let u = user;
|
||||||
|
cx.render(rsx!{
|
||||||
|
tr {
|
||||||
|
// key: "{index}",
|
||||||
|
td {
|
||||||
|
class: "px-6 py-4 border-b border-gray-200 whitespace-nowrap",
|
||||||
|
div {
|
||||||
|
class: "flex items-center",
|
||||||
|
div {
|
||||||
|
class: "flex-shrink-0 w-10 h-10",
|
||||||
|
img {
|
||||||
|
class: "w-10 h-10 rounded-full",
|
||||||
|
alt: "",
|
||||||
|
src: "https://images.unsplash.com/photo-1472099645785-5658abf4ff4e?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2&w=256&h=256&q=80",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
div {
|
||||||
|
class: "ml-4",
|
||||||
|
div {
|
||||||
|
class: "text-sm font-medium leading-5 text-gray-900",
|
||||||
|
"{ u.name }"
|
||||||
|
}
|
||||||
|
div {
|
||||||
|
class: "text-sm leading-5 text-gray-500",
|
||||||
|
"{ u.email }"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
td {
|
||||||
|
class: "px-6 py-4 border-b border-gray-200 whitespace-nowrap",
|
||||||
|
div {
|
||||||
|
class: "text-sm leading-5 text-gray-900",
|
||||||
|
"{ u.title }"
|
||||||
|
}
|
||||||
|
div {
|
||||||
|
class: "text-sm leading-5 text-gray-500",
|
||||||
|
"{ u.title2 }"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
td {
|
||||||
|
class: "px-6 py-4 border-b border-gray-200 whitespace-nowrap",
|
||||||
|
span {
|
||||||
|
class: "inline-flex px-2 text-xs font-semibold leading-5 text-green-800 bg-green-100 rounded-full",
|
||||||
|
"{ u.status }"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
td {
|
||||||
|
class: "px-6 py-4 text-sm leading-5 text-gray-500 border-b border-gray-200 whitespace-nowrap",
|
||||||
|
"{ u.role }"
|
||||||
|
}
|
||||||
|
td {
|
||||||
|
class: "px-6 py-4 text-sm font-medium leading-5 text-right border-b border-gray-200 whitespace-nowrap",
|
||||||
|
a {
|
||||||
|
class: "text-indigo-600 hover:text-indigo-900",
|
||||||
|
href: "#","Edit"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
mod icons{
|
||||||
|
use dioxus::prelude::*;
|
||||||
|
use dioxus_html_macro::html;
|
||||||
|
|
||||||
|
pub fn icon_1(cx: Scope)->Element{
|
||||||
|
cx.render(html!{
|
||||||
|
<svg
|
||||||
|
class="w-8 h-8 text-white"
|
||||||
|
view_box="0 0 28 30"
|
||||||
|
fill="none"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M18.2 9.08889C18.2 11.5373 16.3196 13.5222 14 13.5222C11.6804 13.5222 9.79999 11.5373 9.79999 9.08889C9.79999 6.64043 11.6804 4.65556 14 4.65556C16.3196 4.65556 18.2 6.64043 18.2 9.08889Z"
|
||||||
|
fill="currentColor"
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
d="M25.2 12.0444C25.2 13.6768 23.9464 15 22.4 15C20.8536 15 19.6 13.6768 19.6 12.0444C19.6 10.4121 20.8536 9.08889 22.4 9.08889C23.9464 9.08889 25.2 10.4121 25.2 12.0444Z"
|
||||||
|
fill="currentColor"
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
d="M19.6 22.3889C19.6 19.1243 17.0927 16.4778 14 16.4778C10.9072 16.4778 8.39999 19.1243 8.39999 22.3889V26.8222H19.6V22.3889Z"
|
||||||
|
fill="currentColor"
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
d="M8.39999 12.0444C8.39999 13.6768 7.14639 15 5.59999 15C4.05359 15 2.79999 13.6768 2.79999 12.0444C2.79999 10.4121 4.05359 9.08889 5.59999 9.08889C7.14639 9.08889 8.39999 10.4121 8.39999 12.0444Z"
|
||||||
|
fill="currentColor"
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
d="M22.4 26.8222V22.3889C22.4 20.8312 22.0195 19.3671 21.351 18.0949C21.6863 18.0039 22.0378 17.9556 22.4 17.9556C24.7197 17.9556 26.6 19.9404 26.6 22.3889V26.8222H22.4Z"
|
||||||
|
fill="currentColor"
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
d="M6.64896 18.0949C5.98058 19.3671 5.59999 20.8312 5.59999 22.3889V26.8222H1.39999V22.3889C1.39999 19.9404 3.2804 17.9556 5.59999 17.9556C5.96219 17.9556 6.31367 18.0039 6.64896 18.0949Z"
|
||||||
|
fill="currentColor"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn icon_2(cx: Scope)->Element{
|
||||||
|
cx.render(html!{
|
||||||
|
<svg
|
||||||
|
class="w-8 h-8 text-white"
|
||||||
|
view_box="0 0 28 28"
|
||||||
|
fill="none"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M4.19999 1.4C3.4268 1.4 2.79999 2.02681 2.79999 2.8C2.79999 3.57319 3.4268 4.2 4.19999 4.2H5.9069L6.33468 5.91114C6.33917 5.93092 6.34409 5.95055 6.34941 5.97001L8.24953 13.5705L6.99992 14.8201C5.23602 16.584 6.48528 19.6 8.97981 19.6H21C21.7731 19.6 22.4 18.9732 22.4 18.2C22.4 17.4268 21.7731 16.8 21 16.8H8.97983L10.3798 15.4H19.6C20.1303 15.4 20.615 15.1004 20.8521 14.6261L25.0521 6.22609C25.2691 5.79212 25.246 5.27673 24.991 4.86398C24.7357 4.45123 24.2852 4.2 23.8 4.2H8.79308L8.35818 2.46044C8.20238 1.83722 7.64241 1.4 6.99999 1.4H4.19999Z"
|
||||||
|
fill="currentColor"
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
d="M22.4 23.1C22.4 24.2598 21.4598 25.2 20.3 25.2C19.1403 25.2 18.2 24.2598 18.2 23.1C18.2 21.9402 19.1403 21 20.3 21C21.4598 21 22.4 21.9402 22.4 23.1Z"
|
||||||
|
fill="currentColor"
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
d="M9.1 25.2C10.2598 25.2 11.2 24.2598 11.2 23.1C11.2 21.9402 10.2598 21 9.1 21C7.9402 21 7 21.9402 7 23.1C7 24.2598 7.9402 25.2 9.1 25.2Z"
|
||||||
|
fill="currentColor"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn icon_3(cx: Scope)->Element{
|
||||||
|
cx.render(html!{
|
||||||
|
<svg
|
||||||
|
class="w-8 h-8 text-white"
|
||||||
|
view_box="0 0 28 28"
|
||||||
|
fill="none"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M6.99998 11.2H21L22.4 23.8H5.59998L6.99998 11.2Z"
|
||||||
|
fill="currentColor"
|
||||||
|
stroke="currentColor"
|
||||||
|
stroke_width="2"
|
||||||
|
stroke_linejoin="round"
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
d="M9.79999 8.4C9.79999 6.08041 11.6804 4.2 14 4.2C16.3196 4.2 18.2 6.08041 18.2 8.4V12.6C18.2 14.9197 16.3196 16.8 14 16.8C11.6804 16.8 9.79999 14.9197 9.79999 12.6V8.4Z"
|
||||||
|
stroke="currentColor"
|
||||||
|
stroke_width="2"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
263
src/views/forms.rs
Normal file
263
src/views/forms.rs
Normal file
@@ -0,0 +1,263 @@
|
|||||||
|
/*
|
||||||
|
* @Author: plucky
|
||||||
|
* @Date: 2022-10-15 00:32:59
|
||||||
|
* @LastEditTime: 2022-10-15 09:45:50
|
||||||
|
* @Description:
|
||||||
|
*/
|
||||||
|
|
||||||
|
#![allow(non_snake_case)]
|
||||||
|
use dioxus::prelude::*;
|
||||||
|
use tracing::info;
|
||||||
|
|
||||||
|
#[derive(Debug, Default)]
|
||||||
|
struct User {
|
||||||
|
pub username: String,
|
||||||
|
pub email: String,
|
||||||
|
pub password: String,
|
||||||
|
pub confirm: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn view(cx: Scope)->Element{
|
||||||
|
|
||||||
|
cx.render(rsx!{
|
||||||
|
div {
|
||||||
|
h3 {
|
||||||
|
class: "text-3xl font-semibold text-gray-700",
|
||||||
|
"Forms"
|
||||||
|
}
|
||||||
|
|
||||||
|
// Modal Form
|
||||||
|
Model_form{}
|
||||||
|
|
||||||
|
// Form Elements
|
||||||
|
Forms{}
|
||||||
|
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Model Form
|
||||||
|
fn Model_form(cx: Scope)->Element{
|
||||||
|
|
||||||
|
cx.render(rsx!{
|
||||||
|
div {
|
||||||
|
class: "mt-4",
|
||||||
|
h4 {
|
||||||
|
class: "text-gray-600",
|
||||||
|
"Model Form"
|
||||||
|
}
|
||||||
|
div {
|
||||||
|
class: "mt-4",
|
||||||
|
div {
|
||||||
|
class: "w-full max-w-sm overflow-hidden bg-white border rounded-md shadow-md",
|
||||||
|
// form
|
||||||
|
form {
|
||||||
|
div {
|
||||||
|
class: "flex items-center justify-between px-5 py-3 text-gray-700 border-b",
|
||||||
|
h3 {
|
||||||
|
class: "text-sm",
|
||||||
|
"Add Category"
|
||||||
|
}
|
||||||
|
button {
|
||||||
|
r#type: "button",
|
||||||
|
onclick: |_| {
|
||||||
|
|
||||||
|
},
|
||||||
|
icons::icon_1 {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
div {
|
||||||
|
class: "px-5 py-6 text-gray-700 bg-gray-200 border-b",
|
||||||
|
label {
|
||||||
|
class: "text-xs",
|
||||||
|
"Name"
|
||||||
|
}
|
||||||
|
div {
|
||||||
|
class: "relative mt-2 rounded-md shadow-sm",
|
||||||
|
span {
|
||||||
|
class: "absolute inset-y-0 left-0 flex items-center pl-3 text-gray-600",
|
||||||
|
icons::icon_2 {}
|
||||||
|
}
|
||||||
|
input {
|
||||||
|
class: "w-full px-12 py-2 border-transparent rounded-md appearance-none focus:border-indigo-600 focus:ring focus:ring-opacity-40 focus:ring-indigo-500",
|
||||||
|
r#type: "text",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
div {
|
||||||
|
class: "flex items-center justify-between px-5 py-3",
|
||||||
|
button {
|
||||||
|
r#type: "button",
|
||||||
|
onclick: |_| {
|
||||||
|
info!("click");
|
||||||
|
|
||||||
|
},
|
||||||
|
class: "px-3 py-1 text-sm text-gray-700 bg-gray-200 rounded-md hover:bg-gray-300 focus:outline-none",
|
||||||
|
"Cancel"
|
||||||
|
}
|
||||||
|
button {
|
||||||
|
class: "px-3 py-1 text-sm text-white bg-indigo-600 rounded-md hover:bg-indigo-500 focus:outline-none",
|
||||||
|
"Save"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// Forms
|
||||||
|
fn Forms(cx: Scope)->Element{
|
||||||
|
let user = use_ref(&cx, || User::default());
|
||||||
|
let ur = user.read();
|
||||||
|
|
||||||
|
cx.render(rsx!{
|
||||||
|
div {
|
||||||
|
class: "mt-8",
|
||||||
|
h4 {
|
||||||
|
class: "text-gray-600",
|
||||||
|
"Forms"
|
||||||
|
}
|
||||||
|
div {
|
||||||
|
class: "mt-4",
|
||||||
|
div {
|
||||||
|
class: "p-6 bg-white rounded-md shadow-md",
|
||||||
|
h2 {
|
||||||
|
class: "text-lg font-semibold text-gray-700 capitalize",
|
||||||
|
"Account settings"
|
||||||
|
}
|
||||||
|
|
||||||
|
form{
|
||||||
|
//action="" methods="post"
|
||||||
|
prevent_default: "onsubmit",
|
||||||
|
onsubmit: move |e|{
|
||||||
|
info!("onsubmit: {:?}", e);
|
||||||
|
info!("onsubmit: {:?}", user.read());
|
||||||
|
},
|
||||||
|
|
||||||
|
div {
|
||||||
|
class: "grid grid-cols-1 gap-6 mt-4 sm:grid-cols-2",
|
||||||
|
div {
|
||||||
|
label {
|
||||||
|
class: "text-gray-700",
|
||||||
|
r#for: "username","Username"
|
||||||
|
}
|
||||||
|
input {
|
||||||
|
class: "w-full mt-2 border-gray-200 rounded-md focus:border-indigo-600 focus:ring focus:ring-opacity-40 focus:ring-indigo-500",
|
||||||
|
r#type: "text",
|
||||||
|
// "v-model: "user.username",
|
||||||
|
// 双向绑定
|
||||||
|
value: "{ur.username}",
|
||||||
|
oninput: {|e|{
|
||||||
|
// info!("oninput{:?}", e);
|
||||||
|
user.write().username=e.value.to_string();
|
||||||
|
}},
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
div {
|
||||||
|
label {
|
||||||
|
class: "text-gray-700",
|
||||||
|
r#for: "emailAddress","Email Address"
|
||||||
|
}
|
||||||
|
input {
|
||||||
|
class: "w-full mt-2 border-gray-200 rounded-md focus:border-indigo-600 focus:ring focus:ring-opacity-40 focus:ring-indigo-500",
|
||||||
|
r#type: "email",
|
||||||
|
// "v-model": "user.email",
|
||||||
|
value: "{ur.email}",
|
||||||
|
oninput: {|e|{
|
||||||
|
user.write().email=e.value.to_string();
|
||||||
|
}},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
div {
|
||||||
|
label {
|
||||||
|
class: "text-gray-700",
|
||||||
|
r#for: "password","Password"
|
||||||
|
}
|
||||||
|
input {
|
||||||
|
class: "w-full mt-2 border-gray-200 rounded-md focus:border-indigo-600 focus:ring focus:ring-opacity-40 focus:ring-indigo-500",
|
||||||
|
r#type: "password",
|
||||||
|
// "v-model": "user.password",
|
||||||
|
value: "{ur.password}",
|
||||||
|
oninput: {|e|{
|
||||||
|
user.write().password=e.value.to_string();
|
||||||
|
}},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
div {
|
||||||
|
label {
|
||||||
|
class: "text-gray-700",
|
||||||
|
r#for: "passwordConfirmation","Password Confirmation"
|
||||||
|
}
|
||||||
|
input {
|
||||||
|
class: "w-full mt-2 border-gray-200 rounded-md focus:border-indigo-600 focus:ring focus:ring-opacity-40 focus:ring-indigo-500",
|
||||||
|
r#type: "password",
|
||||||
|
// "v-model": "user.confirm",
|
||||||
|
value: "{ur.confirm}",
|
||||||
|
oninput: {|e|{
|
||||||
|
user.write().confirm=e.value.to_string();
|
||||||
|
}},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
div {
|
||||||
|
class: "flex justify-end mt-4",
|
||||||
|
button {
|
||||||
|
r#type: "submit",
|
||||||
|
class: "px-4 py-2 text-gray-200 bg-gray-800 rounded-md hover:bg-gray-700 focus:outline-none focus:bg-gray-700",
|
||||||
|
"Save"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
mod icons{
|
||||||
|
use dioxus::prelude::*;
|
||||||
|
use dioxus_html_macro::html;
|
||||||
|
|
||||||
|
pub fn icon_1(cx: Scope)->Element{
|
||||||
|
cx.render(html!{
|
||||||
|
<svg
|
||||||
|
class="w-4 h-4"
|
||||||
|
fill="none"
|
||||||
|
view_box="0 0 24 24"
|
||||||
|
stroke="currentColor"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
stroke_linecap="round"
|
||||||
|
stroke_linejoin="round"
|
||||||
|
stroke_width="2"
|
||||||
|
d="M6 18L18 6M6 6l12 12"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn icon_2(cx: Scope)->Element{
|
||||||
|
cx.render(html!{
|
||||||
|
<svg
|
||||||
|
class="w-6 h-6"
|
||||||
|
fill="none"
|
||||||
|
view_box="0 0 24 24"
|
||||||
|
stroke="currentColor"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
stroke_linecap="round"
|
||||||
|
stroke_linejoin="round"
|
||||||
|
stroke_width="2"
|
||||||
|
d="M11 4a2 2 0 114 0v1a1 1 0 001 1h3a1 1 0 011 1v3a1 1 0 01-1 1h-1a2 2 0 100 4h1a1 1 0 011 1v3a1 1 0 01-1 1h-3a1 1 0 01-1-1v-1a2 2 0 10-4 0v1a1 1 0 01-1 1H7a1 1 0 01-1-1v-3a1 1 0 00-1-1H4a2 2 0 110-4h1a1 1 0 001-1V7a1 1 0 011-1h3a1 1 0 001-1V4z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
138
src/views/login.rs
Normal file
138
src/views/login.rs
Normal file
@@ -0,0 +1,138 @@
|
|||||||
|
/*
|
||||||
|
* @Author: plucky
|
||||||
|
* @Date: 2022-10-12 00:00:54
|
||||||
|
* @LastEditTime: 2022-10-14 16:54:55
|
||||||
|
* @Description:
|
||||||
|
*/
|
||||||
|
use dioxus::prelude::*;
|
||||||
|
|
||||||
|
pub fn view(cx: Scope)->Element{
|
||||||
|
let email = use_state(&cx, ||"".to_string());
|
||||||
|
let password = use_state(&cx, ||"".to_string());
|
||||||
|
// function login() {
|
||||||
|
// router.push("/dashboard");
|
||||||
|
// }
|
||||||
|
let router = use_router(&cx);
|
||||||
|
|
||||||
|
cx.render(rsx!{
|
||||||
|
div {
|
||||||
|
class: "flex items-center justify-center h-screen px-6 bg-gray-200",
|
||||||
|
div {
|
||||||
|
class: "w-full max-w-sm p-6 bg-white rounded-md shadow-md",
|
||||||
|
div {
|
||||||
|
class: "flex items-center justify-center",
|
||||||
|
icons::icon_1 {}
|
||||||
|
span {
|
||||||
|
class: "text-2xl font-semibold text-gray-700",
|
||||||
|
"V-Dashboard"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
form{
|
||||||
|
class: "mt-4",
|
||||||
|
//@submit.prevent="login"
|
||||||
|
onsubmit: move |_|{
|
||||||
|
// login();
|
||||||
|
router.push_route("/dashboard", None, None);
|
||||||
|
},
|
||||||
|
label {
|
||||||
|
class: "block",
|
||||||
|
span {
|
||||||
|
class: "text-sm text-gray-700",
|
||||||
|
"Email"
|
||||||
|
}
|
||||||
|
input {
|
||||||
|
class: "block w-full mt-1 border-gray-200 rounded-md focus:border-indigo-600 focus:ring focus:ring-opacity-40 focus:ring-indigo-500",
|
||||||
|
r#type: "email",
|
||||||
|
// "v-model": "email",
|
||||||
|
placeholder: "Enter your email",
|
||||||
|
// value: "{email}",
|
||||||
|
oninput: move |e| {
|
||||||
|
email.set(e.value.clone());
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
label {
|
||||||
|
class: "block mt-3",
|
||||||
|
span {
|
||||||
|
class: "text-sm text-gray-700",
|
||||||
|
"Password"
|
||||||
|
}
|
||||||
|
input {
|
||||||
|
class: "block w-full mt-1 border-gray-200 rounded-md focus:border-indigo-600 focus:ring focus:ring-opacity-40 focus:ring-indigo-500",
|
||||||
|
r#type: "password",
|
||||||
|
// "v-model": "password",
|
||||||
|
placeholder: "Enter your password",
|
||||||
|
value: "{password}",
|
||||||
|
oninput: move |e| {
|
||||||
|
password.set(e.value.clone());
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
div {
|
||||||
|
class: "flex items-center justify-between mt-4",
|
||||||
|
div {
|
||||||
|
label {
|
||||||
|
class: "inline-flex items-center",
|
||||||
|
input {
|
||||||
|
class: "text-indigo-600 border-gray-200 rounded-md focus:border-indigo-600 focus:ring focus:ring-opacity-40 focus:ring-indigo-500",
|
||||||
|
r#type: "checkbox",
|
||||||
|
}
|
||||||
|
span {
|
||||||
|
class: "mx-2 text-sm text-gray-600",
|
||||||
|
"Remember me"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
div {
|
||||||
|
a {
|
||||||
|
class: "block text-sm text-indigo-700 fontme hover:underline",
|
||||||
|
href: "#", "Forgot your password?"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
div {
|
||||||
|
class: "mt-6",
|
||||||
|
button {
|
||||||
|
class: "w-full px-4 py-2 text-sm text-center text-white bg-indigo-600 rounded-md focus:outline-none hover:bg-indigo-500",
|
||||||
|
r#type: "submit", "Sign in"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
mod icons{
|
||||||
|
use dioxus::prelude::*;
|
||||||
|
use dioxus_html_macro::html;
|
||||||
|
|
||||||
|
pub fn icon_1(cx: Scope)->Element{
|
||||||
|
cx.render(html!{
|
||||||
|
<svg
|
||||||
|
class="w-10 h-10"
|
||||||
|
view_box="0 0 512 512"
|
||||||
|
fill="none"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M364.61 390.213C304.625 450.196 207.37 450.196 147.386 390.213C117.394 360.22 102.398 320.911 102.398 281.6C102.398 242.291 117.394 202.981 147.386 172.989C147.386 230.4 153.6 281.6 230.4 307.2C230.4 256 256 102.4 294.4 76.7999C320 128 334.618 142.997 364.608 172.989C394.601 202.981 409.597 242.291 409.597 281.6C409.597 320.911 394.601 360.22 364.61 390.213Z"
|
||||||
|
fill="#4C51BF"
|
||||||
|
stroke="#4C51BF"
|
||||||
|
stroke_width="2"
|
||||||
|
stroke_linecap="round"
|
||||||
|
stroke_linejoin="round"
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
d="M201.694 387.105C231.686 417.098 280.312 417.098 310.305 387.105C325.301 372.109 332.8 352.456 332.8 332.8C332.8 313.144 325.301 293.491 310.305 278.495C295.309 263.498 288 256 275.2 230.4C256 243.2 243.201 320 243.201 345.6C201.694 345.6 179.2 332.8 179.2 332.8C179.2 352.456 186.698 372.109 201.694 387.105Z"
|
||||||
|
fill="white"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
25
src/views/mod.rs
Normal file
25
src/views/mod.rs
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
/*
|
||||||
|
* @Author: plucky
|
||||||
|
* @Date: 2022-10-11 23:13:24
|
||||||
|
* @LastEditTime: 2022-10-15 09:53:40
|
||||||
|
* @Description:
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
pub mod login;
|
||||||
|
pub mod dashboard;
|
||||||
|
pub mod ui_elements;
|
||||||
|
pub mod tables;
|
||||||
|
pub mod forms;
|
||||||
|
pub mod card;
|
||||||
|
pub mod modal;
|
||||||
|
pub mod blank;
|
||||||
|
|
||||||
|
|
||||||
|
// pub fn view(cx: Scope)->Element{
|
||||||
|
|
||||||
|
// cx.render(rsx!{
|
||||||
|
// div {
|
||||||
|
// }
|
||||||
|
// })
|
||||||
|
// }
|
||||||
126
src/views/modal.rs
Normal file
126
src/views/modal.rs
Normal file
@@ -0,0 +1,126 @@
|
|||||||
|
/*
|
||||||
|
* @Author: plucky
|
||||||
|
* @Date: 2022-10-15 09:52:14
|
||||||
|
* @LastEditTime: 2022-10-15 11:24:14
|
||||||
|
* @Description:
|
||||||
|
*/
|
||||||
|
|
||||||
|
use dioxus::prelude::*;
|
||||||
|
|
||||||
|
pub fn view(cx: Scope)->Element{
|
||||||
|
let open = use_state(&cx, || false);
|
||||||
|
// let modal = "transition: opacity 0.25s ease";
|
||||||
|
|
||||||
|
cx.render(rsx!{
|
||||||
|
div {
|
||||||
|
h3 {
|
||||||
|
class: "text-3xl font-medium text-gray-700",
|
||||||
|
"Modal"
|
||||||
|
}
|
||||||
|
// open modal
|
||||||
|
button {
|
||||||
|
onclick: move |_| {
|
||||||
|
open.set(true);
|
||||||
|
},
|
||||||
|
class: "px-6 py-3 mt-3 font-medium tracking-wide text-white bg-indigo-600 rounded-md hover:bg-indigo-500 focus:outline-none",
|
||||||
|
"Open Modal",
|
||||||
|
}
|
||||||
|
|
||||||
|
// Modal
|
||||||
|
div{
|
||||||
|
class: format_args!("transition:opacity 0.25s ease {}", if !open.get(){"opacity-0 pointer-events-none"}else{"z-50 fixed w-full h-full top-0 left-0 flex items-center justify-center"}),
|
||||||
|
// overlay
|
||||||
|
div{
|
||||||
|
class: "absolute w-full h-full bg-gray-900 opacity-50 modal-overlay",
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
div {
|
||||||
|
class: "z-50 w-11/12 mx-auto overflow-y-auto bg-white rounded shadow-lg modal-container md:max-w-md",
|
||||||
|
// 右上角关闭按钮
|
||||||
|
div {
|
||||||
|
onclick: move |_| {
|
||||||
|
open.set(false);
|
||||||
|
},
|
||||||
|
class: "absolute top-0 right-0 z-50 flex flex-col items-center mt-4 mr-4 text-sm text-white cursor-pointer modal-close",
|
||||||
|
icons::icon_1 {}
|
||||||
|
span {
|
||||||
|
class: "text-sm",
|
||||||
|
"(Esc)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//<!-- Add margin if you want to see some of the overlay behind the modal-->
|
||||||
|
div {
|
||||||
|
class: "px-6 py-4 text-left modal-content",
|
||||||
|
//<!--Title-->
|
||||||
|
div {
|
||||||
|
class: "flex items-center justify-between pb-3",
|
||||||
|
p {
|
||||||
|
class: "text-2xl font-bold",
|
||||||
|
"Modal Title"
|
||||||
|
}
|
||||||
|
div{
|
||||||
|
class: "z-50 cursor-pointer modal-close",
|
||||||
|
onclick: move |_| {
|
||||||
|
open.set(false);
|
||||||
|
},
|
||||||
|
icons::icon_1 {}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//<!--Body-->
|
||||||
|
p {"Modal content."}
|
||||||
|
|
||||||
|
//<!--Footer-->
|
||||||
|
div {
|
||||||
|
class: "flex justify-end pt-2",
|
||||||
|
button {
|
||||||
|
onclick: move |_| {
|
||||||
|
open.set(false);
|
||||||
|
},
|
||||||
|
class: "p-3 px-6 py-3 mr-2 text-indigo-500 bg-transparent rounded-lg hover:bg-gray-100 hover:text-indigo-400 focus:outline-none",
|
||||||
|
"Close"
|
||||||
|
}
|
||||||
|
button {
|
||||||
|
onclick: move |_| {
|
||||||
|
open.set(false);
|
||||||
|
},
|
||||||
|
class: "px-6 py-3 font-medium tracking-wide text-white bg-indigo-600 rounded-md hover:bg-indigo-500 focus:outline-none",
|
||||||
|
"Action"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
mod icons{
|
||||||
|
use dioxus::prelude::*;
|
||||||
|
use dioxus_html_macro::html;
|
||||||
|
|
||||||
|
pub fn icon_1(cx: Scope)->Element{
|
||||||
|
cx.render(html!{
|
||||||
|
<svg
|
||||||
|
class="w-5 h-5"
|
||||||
|
fill="none"
|
||||||
|
view_box="0 0 24 24"
|
||||||
|
stroke="currentColor"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
stroke_linecap="round"
|
||||||
|
stroke_linejoin="round"
|
||||||
|
stroke_width="2"
|
||||||
|
d="M6 18L18 6M6 6l12 12"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
458
src/views/tables.rs
Normal file
458
src/views/tables.rs
Normal file
@@ -0,0 +1,458 @@
|
|||||||
|
/*
|
||||||
|
* @Author: plucky
|
||||||
|
* @Date: 2022-10-14 17:43:39
|
||||||
|
* @LastEditTime: 2022-10-15 00:21:14
|
||||||
|
* @Description:
|
||||||
|
*/
|
||||||
|
#![allow(non_snake_case)]
|
||||||
|
use dioxus::prelude::*;
|
||||||
|
|
||||||
|
use crate::modules::demo_data::USE_TABLE_DATA;
|
||||||
|
|
||||||
|
pub fn view(cx: Scope)->Element{
|
||||||
|
|
||||||
|
cx.render(rsx!{
|
||||||
|
div {
|
||||||
|
h3 {
|
||||||
|
class: "text-3xl font-medium text-gray-700",
|
||||||
|
"Tables"
|
||||||
|
}
|
||||||
|
// Simple Table
|
||||||
|
Simple_table{}
|
||||||
|
|
||||||
|
// Table with pagination
|
||||||
|
Table_with_pagination{}
|
||||||
|
|
||||||
|
// Wide Table
|
||||||
|
Wide_table{}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// Simple Table
|
||||||
|
fn Simple_table(cx: Scope)->Element{
|
||||||
|
let simple_table_data = &use_read(&cx, USE_TABLE_DATA).simpleTableData;
|
||||||
|
|
||||||
|
cx.render(rsx!{
|
||||||
|
div {
|
||||||
|
class: "mt-4",
|
||||||
|
h4 {
|
||||||
|
class: "text-gray-600",
|
||||||
|
"Simple Table"
|
||||||
|
}
|
||||||
|
div {
|
||||||
|
class: "mt-6",
|
||||||
|
div {
|
||||||
|
class: "my-6 overflow-hidden bg-white rounded-md shadow",
|
||||||
|
table {
|
||||||
|
class: "w-full text-left border-collapse",
|
||||||
|
thead {
|
||||||
|
class: "border-b",
|
||||||
|
tr {
|
||||||
|
th {
|
||||||
|
class: "px-5 py-3 text-sm font-medium text-gray-100 uppercase bg-indigo-800",
|
||||||
|
"City"
|
||||||
|
}
|
||||||
|
th {
|
||||||
|
class: "px-5 py-3 text-sm font-medium text-gray-100 uppercase bg-indigo-800",
|
||||||
|
"Total orders"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// data
|
||||||
|
tbody {
|
||||||
|
simple_table_data.iter().enumerate().map(|(i,data)|{
|
||||||
|
rsx!{ tr {
|
||||||
|
class: "hover:bg-gray-200",
|
||||||
|
key: "{i}",
|
||||||
|
td {
|
||||||
|
class: "px-6 py-4 text-lg text-gray-700 border-b",
|
||||||
|
"{data.city}"
|
||||||
|
}
|
||||||
|
td {
|
||||||
|
class: "px-6 py-4 text-gray-500 border-b",
|
||||||
|
"{data.totalOrders}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 分页 table
|
||||||
|
// Table with pagination
|
||||||
|
fn Table_with_pagination(cx: Scope)->Element{
|
||||||
|
let paginated_table_data = &use_read(&cx, USE_TABLE_DATA).paginatedTableData;
|
||||||
|
|
||||||
|
let status_color = |status: &str| {
|
||||||
|
match status {
|
||||||
|
"Active" => ("bg-green-100", "text-green-800"),
|
||||||
|
"Inactive" => ("bg-red-100", "text-red-800"),
|
||||||
|
"Suspended" => ("bg-orange-100", "text-orange-800"),
|
||||||
|
_ => ("bg-gray-100", "text-gray-800"),
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
cx.render(rsx!{
|
||||||
|
div {
|
||||||
|
class: "mt-8",
|
||||||
|
h4 {
|
||||||
|
class: "text-gray-600",
|
||||||
|
"Table with pagination"
|
||||||
|
}
|
||||||
|
div {
|
||||||
|
class: "mt-6",
|
||||||
|
h2 {
|
||||||
|
class: "text-xl font-semibold leading-tight text-gray-700",
|
||||||
|
"Users"
|
||||||
|
}
|
||||||
|
// limit
|
||||||
|
div {
|
||||||
|
class: "flex flex-col mt-3 sm:flex-row",
|
||||||
|
div {
|
||||||
|
class: "flex",
|
||||||
|
div {
|
||||||
|
class: "relative",
|
||||||
|
select {
|
||||||
|
class: "block w-full h-full px-4 py-2 pr-8 leading-tight text-gray-700 bg-white border border-gray-400 rounded-l appearance-none focus:outline-none focus:bg-white focus:border-gray-500",
|
||||||
|
option {
|
||||||
|
"5"
|
||||||
|
}
|
||||||
|
option {
|
||||||
|
"10"
|
||||||
|
}
|
||||||
|
option {
|
||||||
|
"20"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
div {
|
||||||
|
class: "absolute inset-y-0 right-0 flex items-center px-2 text-gray-700 pointer-events-none",
|
||||||
|
icons::icon_1 {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
div {
|
||||||
|
class: "relative",
|
||||||
|
select {
|
||||||
|
class: "block w-full h-full px-4 py-2 pr-8 leading-tight text-gray-700 bg-white border-t border-b border-r border-gray-400 rounded-r appearance-none sm:rounded-r-none sm:border-r-0 focus:outline-none focus:border-l focus:border-r focus:bg-white focus:border-gray-500",
|
||||||
|
option {
|
||||||
|
"All"
|
||||||
|
}
|
||||||
|
option {
|
||||||
|
"Active"
|
||||||
|
}
|
||||||
|
option {
|
||||||
|
"Inactive"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
div {
|
||||||
|
class: "absolute inset-y-0 right-0 flex items-center px-2 text-gray-700 pointer-events-none",
|
||||||
|
icons::icon_2 {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
div {
|
||||||
|
class: "relative block mt-2 sm:mt-0",
|
||||||
|
span {
|
||||||
|
class: "absolute inset-y-0 left-0 flex items-center pl-2",
|
||||||
|
icons::icon_3 {}
|
||||||
|
}
|
||||||
|
input {
|
||||||
|
class: "block w-full py-2 pl-8 pr-6 text-sm text-gray-700 placeholder-gray-400 bg-white border border-b border-gray-400 rounded-l rounded-r appearance-none sm:rounded-l-none focus:bg-white focus:placeholder-gray-600 focus:text-gray-700 focus:outline-none",
|
||||||
|
placeholder: "Search",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// table
|
||||||
|
div {
|
||||||
|
class: "px-4 py-4 -mx-4 overflow-x-auto sm:-mx-8 sm:px-8",
|
||||||
|
div {
|
||||||
|
class: "inline-block min-w-full overflow-hidden rounded-lg shadow",
|
||||||
|
table {
|
||||||
|
class: "min-w-full leading-normal",
|
||||||
|
// table header
|
||||||
|
thead {
|
||||||
|
tr {
|
||||||
|
th {
|
||||||
|
class: "px-5 py-3 text-xs font-semibold tracking-wider text-left text-gray-600 uppercase bg-gray-100 border-b-2 border-gray-200",
|
||||||
|
"User"
|
||||||
|
}
|
||||||
|
th {
|
||||||
|
class: "px-5 py-3 text-xs font-semibold tracking-wider text-left text-gray-600 uppercase bg-gray-100 border-b-2 border-gray-200",
|
||||||
|
"Role"
|
||||||
|
}
|
||||||
|
th {
|
||||||
|
class: "px-5 py-3 text-xs font-semibold tracking-wider text-left text-gray-600 uppercase bg-gray-100 border-b-2 border-gray-200",
|
||||||
|
"Created at"
|
||||||
|
}
|
||||||
|
th {
|
||||||
|
class: "px-5 py-3 text-xs font-semibold tracking-wider text-left text-gray-600 uppercase bg-gray-100 border-b-2 border-gray-200",
|
||||||
|
"Status"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// data
|
||||||
|
tbody {
|
||||||
|
// "<tr v-for=\"(u, index) in paginatedTableData\" :key=\"index\">"
|
||||||
|
paginated_table_data.iter().map(|u|{rsx!{
|
||||||
|
tr{
|
||||||
|
// key: "{u.id}",
|
||||||
|
td {
|
||||||
|
class: "px-5 py-5 text-sm bg-white border-b border-gray-200",
|
||||||
|
div {
|
||||||
|
class: "flex items-center",
|
||||||
|
div {
|
||||||
|
class: "flex-shrink-0 w-10 h-10",
|
||||||
|
img {
|
||||||
|
class: "w-full h-full rounded-full",
|
||||||
|
src: "{u.picture}",
|
||||||
|
alt: "profile pic",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
div {
|
||||||
|
class: "ml-3",
|
||||||
|
p {
|
||||||
|
class: "text-gray-900 whitespace-nowrap",
|
||||||
|
"{ u.name }"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
td {
|
||||||
|
class: "px-5 py-5 text-sm bg-white border-b border-gray-200",
|
||||||
|
p {
|
||||||
|
class: "text-gray-900 whitespace-nowrap",
|
||||||
|
"{ u.role }"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
td {
|
||||||
|
class: "px-5 py-5 text-sm bg-white border-b border-gray-200",
|
||||||
|
p {
|
||||||
|
class: "text-gray-900 whitespace-nowrap",
|
||||||
|
"{ u.created }"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
td {
|
||||||
|
class: "px-5 py-5 text-sm bg-white border-b border-gray-200",
|
||||||
|
span {
|
||||||
|
class: format_args!("inline-flex px-3 py-1 font-semibold leading-tight rounded-full {} {}",status_color(&u.status).0,status_color(&u.status).1),
|
||||||
|
"{ u.status }"
|
||||||
|
}
|
||||||
|
|
||||||
|
// span {
|
||||||
|
// class: format_args!("relative inline-block px-3 py-1 font-semibold leading-tight {}", status_color(&u.status).1),
|
||||||
|
// span {
|
||||||
|
// aria_hidden: "true",
|
||||||
|
// class: {
|
||||||
|
// format_args!("absolute inset-0 opacity-50 rounded-full {}", status_color(&u.status).0)
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// span {
|
||||||
|
// class: "relative",
|
||||||
|
// "{u.status}"
|
||||||
|
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
//tr end
|
||||||
|
}
|
||||||
|
// iter end
|
||||||
|
}})
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
div {
|
||||||
|
class: "flex flex-col items-center px-5 py-5 bg-white border-t xs:flex-row xs:justify-between",
|
||||||
|
span {
|
||||||
|
class: "text-xs text-gray-900 xs:text-sm",
|
||||||
|
"Showing 1 to 4 of 50 Entries"
|
||||||
|
}
|
||||||
|
div {
|
||||||
|
class: "inline-flex mt-2 xs:mt-0",
|
||||||
|
button {
|
||||||
|
class: "px-4 py-2 text-sm font-semibold text-gray-800 bg-gray-300 rounded-l hover:bg-gray-400",
|
||||||
|
"Prev"
|
||||||
|
}
|
||||||
|
button {
|
||||||
|
class: "px-4 py-2 text-sm font-semibold text-gray-800 bg-gray-300 rounded-r hover:bg-gray-400",
|
||||||
|
"Next"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 宽表格
|
||||||
|
fn Wide_table(cx: Scope)->Element{
|
||||||
|
let wide_table_data = &use_read(&cx, USE_TABLE_DATA).wideTableData;
|
||||||
|
|
||||||
|
cx.render(rsx!{
|
||||||
|
div {
|
||||||
|
class: "mt-8",
|
||||||
|
h4 {
|
||||||
|
class: "text-gray-600",
|
||||||
|
"Wide Table"
|
||||||
|
}
|
||||||
|
div {
|
||||||
|
class: "flex flex-col mt-6",
|
||||||
|
div {
|
||||||
|
class: "py-2 -my-2 overflow-x-auto sm:-mx-6 sm:px-6 lg:-mx-8 lg:px-8",
|
||||||
|
div {
|
||||||
|
class: "inline-block min-w-full overflow-hidden align-middle border-b border-gray-200 shadow sm:rounded-lg",
|
||||||
|
table {
|
||||||
|
class: "min-w-full",
|
||||||
|
thead {
|
||||||
|
tr {
|
||||||
|
th {
|
||||||
|
class: "px-6 py-3 text-xs font-medium leading-4 tracking-wider text-left text-gray-500 uppercase bg-gray-100 border-b border-gray-200",
|
||||||
|
"Name"
|
||||||
|
}
|
||||||
|
th {
|
||||||
|
class: "px-6 py-3 text-xs font-medium leading-4 tracking-wider text-left text-gray-500 uppercase bg-gray-100 border-b border-gray-200",
|
||||||
|
"Title"
|
||||||
|
}
|
||||||
|
th {
|
||||||
|
class: "px-6 py-3 text-xs font-medium leading-4 tracking-wider text-left text-gray-500 uppercase bg-gray-100 border-b border-gray-200",
|
||||||
|
"Status"
|
||||||
|
}
|
||||||
|
th {
|
||||||
|
class: "px-6 py-3 text-xs font-medium leading-4 tracking-wider text-left text-gray-500 uppercase bg-gray-100 border-b border-gray-200",
|
||||||
|
"Role"
|
||||||
|
}
|
||||||
|
th {
|
||||||
|
class: "px-6 py-3 bg-gray-100 border-b border-gray-200",
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// data
|
||||||
|
tbody {
|
||||||
|
class: "bg-white",
|
||||||
|
// iter start
|
||||||
|
wide_table_data.iter().map(|u|{rsx!{tr{
|
||||||
|
|
||||||
|
td {
|
||||||
|
class: "px-6 py-4 border-b border-gray-200 whitespace-nowrap",
|
||||||
|
div {
|
||||||
|
class: "flex items-center",
|
||||||
|
div {
|
||||||
|
class: "flex-shrink-0 w-10 h-10",
|
||||||
|
img {
|
||||||
|
class: "w-10 h-10 rounded-full",
|
||||||
|
alt: "profile pic",
|
||||||
|
src: "https://images.unsplash.com/photo-1472099645785-5658abf4ff4e?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2&w=256&h=256&q=80",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
div {
|
||||||
|
class: "ml-4",
|
||||||
|
div {
|
||||||
|
class: "text-sm font-medium leading-5 text-gray-900",
|
||||||
|
"{u.name}"
|
||||||
|
}
|
||||||
|
div {
|
||||||
|
class: "text-sm leading-5 text-gray-500",
|
||||||
|
"{ u.email }"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
td {
|
||||||
|
class: "px-6 py-4 border-b border-gray-200 whitespace-nowrap",
|
||||||
|
div {
|
||||||
|
class: "text-sm leading-5 text-gray-900",
|
||||||
|
"{ u.title }"
|
||||||
|
}
|
||||||
|
div {
|
||||||
|
class: "text-sm leading-5 text-gray-500",
|
||||||
|
"{ u.title2 }"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
td {
|
||||||
|
class: "px-6 py-4 border-b border-gray-200 whitespace-nowrap",
|
||||||
|
span {
|
||||||
|
class: "inline-flex px-2 text-xs font-semibold leading-5 text-green-800 bg-green-100 rounded-full",
|
||||||
|
"{ u.status }"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
td {
|
||||||
|
class: "px-6 py-4 text-sm leading-5 text-gray-500 border-b border-gray-200 whitespace-nowrap",
|
||||||
|
"{ u.role }"
|
||||||
|
}
|
||||||
|
td {
|
||||||
|
class: "px-6 py-4 text-sm font-medium leading-5 text-right border-b border-gray-200 whitespace-nowrap",
|
||||||
|
a {
|
||||||
|
class: "text-indigo-600 hover:text-indigo-900",
|
||||||
|
href: "#","Edit"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// iter end
|
||||||
|
}}})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
mod icons{
|
||||||
|
use dioxus::prelude::*;
|
||||||
|
use dioxus_html_macro::html;
|
||||||
|
|
||||||
|
pub fn icon_1(cx: Scope)->Element{
|
||||||
|
cx.render(html!{
|
||||||
|
<svg
|
||||||
|
class="w-4 h-4 fill-current"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
view_box="0 0 20 20"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M9.293 12.95l.707.707L15.657 8l-1.414-1.414L10 10.828 5.757 6.586 4.343 8z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn icon_2(cx: Scope)->Element{
|
||||||
|
cx.render(html!{
|
||||||
|
<svg
|
||||||
|
class="w-4 h-4 fill-current"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
view_box="0 0 20 20"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M9.293 12.95l.707.707L15.657 8l-1.414-1.414L10 10.828 5.757 6.586 4.343 8z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn icon_3(cx: Scope)->Element{
|
||||||
|
cx.render(html!{
|
||||||
|
<svg
|
||||||
|
view_box="0 0 24 24"
|
||||||
|
class="w-4 h-4 text-gray-500 fill-current"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M10 4a6 6 0 100 12 6 6 0 000-12zm-8 6a8 8 0 1114.32 4.906l5.387 5.387a1 1 0 01-1.414 1.414l-5.387-5.387A8 8 0 012 10z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
365
src/views/ui_elements.rs
Normal file
365
src/views/ui_elements.rs
Normal file
@@ -0,0 +1,365 @@
|
|||||||
|
/*
|
||||||
|
* @Author: plucky
|
||||||
|
* @Date: 2022-10-14 16:04:10
|
||||||
|
* @LastEditTime: 2022-10-14 16:21:17
|
||||||
|
* @Description:
|
||||||
|
*/
|
||||||
|
|
||||||
|
use dioxus::prelude::*;
|
||||||
|
|
||||||
|
pub fn view(cx: Scope)->Element{
|
||||||
|
|
||||||
|
cx.render(rsx!{
|
||||||
|
div {
|
||||||
|
h3 {
|
||||||
|
class: "text-3xl font-medium text-gray-700",
|
||||||
|
"UI Elements"
|
||||||
|
}
|
||||||
|
// alerts
|
||||||
|
div {
|
||||||
|
class: "mt-4",
|
||||||
|
h4 {
|
||||||
|
class: "text-gray-600",
|
||||||
|
"Alerts"
|
||||||
|
}
|
||||||
|
div {
|
||||||
|
class: "mt-4",
|
||||||
|
div {
|
||||||
|
class: "px-4 py-4 overflow-x-auto bg-white rounded-md whitespace-nowrap",
|
||||||
|
div {
|
||||||
|
class: "inline-flex w-full max-w-sm ml-3 overflow-hidden bg-white rounded-lg shadow-md",
|
||||||
|
div {
|
||||||
|
class: "flex items-center justify-center w-12 bg-green-500",
|
||||||
|
icons::icon_1 {}
|
||||||
|
}
|
||||||
|
div {
|
||||||
|
class: "px-4 py-2 -mx-3",
|
||||||
|
div {
|
||||||
|
class: "mx-3",
|
||||||
|
span {
|
||||||
|
class: "font-semibold text-green-500",
|
||||||
|
"Success"
|
||||||
|
}
|
||||||
|
p {
|
||||||
|
class: "text-sm text-gray-600",
|
||||||
|
"Your account was registered!"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
div {
|
||||||
|
class: "inline-flex w-full max-w-sm ml-3 overflow-hidden bg-white rounded-lg shadow-md",
|
||||||
|
div {
|
||||||
|
class: "flex items-center justify-center w-12 bg-blue-500",
|
||||||
|
icons::icon_2 {}
|
||||||
|
}
|
||||||
|
div {
|
||||||
|
class: "px-4 py-2 -mx-3",
|
||||||
|
div {
|
||||||
|
class: "mx-3",
|
||||||
|
span {
|
||||||
|
class: "font-semibold text-blue-500",
|
||||||
|
"Info"
|
||||||
|
}
|
||||||
|
p {
|
||||||
|
class: "text-sm text-gray-600",
|
||||||
|
"Channel archived by the owner."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
div {
|
||||||
|
class: "inline-flex w-full max-w-sm ml-3 overflow-hidden bg-white rounded-lg shadow-md",
|
||||||
|
div {
|
||||||
|
class: "flex items-center justify-center w-12 bg-yellow-500",
|
||||||
|
icons::icon_3 {}
|
||||||
|
}
|
||||||
|
div {
|
||||||
|
class: "px-4 py-2 -mx-3",
|
||||||
|
div {
|
||||||
|
class: "mx-3",
|
||||||
|
span {
|
||||||
|
class: "font-semibold text-yellow-500",
|
||||||
|
"Warning"
|
||||||
|
}
|
||||||
|
p {
|
||||||
|
class: "text-sm text-gray-600",
|
||||||
|
"Image size is too large."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
div {
|
||||||
|
class: "inline-flex w-full max-w-sm ml-3 overflow-hidden bg-white rounded-lg shadow-md",
|
||||||
|
div {
|
||||||
|
class: "flex items-center justify-center w-12 bg-red-500",
|
||||||
|
icons::icon_4 {}
|
||||||
|
}
|
||||||
|
div {
|
||||||
|
class: "px-4 py-2 -mx-3",
|
||||||
|
div {
|
||||||
|
class: "mx-3",
|
||||||
|
span {
|
||||||
|
class: "font-semibold text-red-500",
|
||||||
|
"Error"
|
||||||
|
}
|
||||||
|
p {
|
||||||
|
class: "text-sm text-gray-600",
|
||||||
|
"Your email is already used!"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Inputs
|
||||||
|
div {
|
||||||
|
class: "mt-8",
|
||||||
|
h4 {
|
||||||
|
class: "text-gray-600",
|
||||||
|
"Inputs"
|
||||||
|
}
|
||||||
|
div {
|
||||||
|
class: "mt-4",
|
||||||
|
div {
|
||||||
|
class: "flex items-center px-4 py-4 space-x-4 overflow-x-auto bg-white rounded-md",
|
||||||
|
label {
|
||||||
|
input {
|
||||||
|
class: "w-5 h-5 text-indigo-600 focus:ring-indigo-500",
|
||||||
|
name: "radio",
|
||||||
|
r#type: "radio",
|
||||||
|
}
|
||||||
|
span {
|
||||||
|
class: "ml-2 text-gray-700",
|
||||||
|
"Radio"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
label {
|
||||||
|
input {
|
||||||
|
class: "w-5 h-5 text-indigo-600 rounded-md focus:ring-indigo-500",
|
||||||
|
name: "radio",
|
||||||
|
r#type: "checkbox",
|
||||||
|
}
|
||||||
|
span {
|
||||||
|
class: "ml-2 text-gray-700",
|
||||||
|
"Checkbox"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
label {
|
||||||
|
class: "block",
|
||||||
|
input {
|
||||||
|
class: "block w-full mt-1 border-gray-200 rounded-md focus:border-indigo-600 focus:ring focus:ring-opacity-40 focus:ring-indigo-500",
|
||||||
|
placeholder: "Email",
|
||||||
|
r#type: "email",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
div {
|
||||||
|
class: "relative mx-4 lg:mx-0",
|
||||||
|
span {
|
||||||
|
class: "absolute inset-y-0 left-0 flex items-center pl-3",
|
||||||
|
icons::icon_5 {}
|
||||||
|
}
|
||||||
|
input {
|
||||||
|
class: "w-32 pl-10 pr-4 text-indigo-600 border-gray-200 rounded-md sm:w-64 focus:border-indigo-600 focus:ring focus:ring-opacity-40 focus:ring-indigo-500",
|
||||||
|
placeholder: "Search",
|
||||||
|
r#type: "text",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Buttons
|
||||||
|
div {
|
||||||
|
class: "mt-8",
|
||||||
|
h4 {
|
||||||
|
class: "text-gray-600",
|
||||||
|
"Buttons"
|
||||||
|
}
|
||||||
|
div {
|
||||||
|
class: "mt-4",
|
||||||
|
div {
|
||||||
|
class: "flex px-4 py-4 space-x-4 overflow-x-auto bg-white rounded-md",
|
||||||
|
button {
|
||||||
|
class: "px-4 py-2 font-medium tracking-wide text-white capitalize transition-colors duration-200 transform bg-indigo-600 rounded-md hover:bg-indigo-500 focus:outline-none focus:bg-indigo-500",
|
||||||
|
"Primary"
|
||||||
|
}
|
||||||
|
button {
|
||||||
|
class: "flex items-center px-2 py-2 font-medium tracking-wide text-white capitalize transition-colors duration-200 transform bg-indigo-600 rounded-md hover:bg-indigo-500 focus:outline-none focus:bg-indigo-500",
|
||||||
|
icons::icon_6 {}
|
||||||
|
span {
|
||||||
|
class: "mx-1",
|
||||||
|
"Refresh"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
div {
|
||||||
|
class: "flex items-center",
|
||||||
|
button {
|
||||||
|
class: "px-4 py-2 font-medium tracking-wide text-white capitalize transition-colors duration-200 transform bg-indigo-600 rounded-md hover:bg-indigo-500 focus:outline-none focus:bg-indigo-500",
|
||||||
|
"Download"
|
||||||
|
}
|
||||||
|
span {
|
||||||
|
class: "border border-transparent",
|
||||||
|
|
||||||
|
}
|
||||||
|
div {
|
||||||
|
class: "relative",
|
||||||
|
button {
|
||||||
|
class: "relative z-10 block p-2 transition-colors duration-200 transform bg-indigo-600 rounded-md hover:bg-indigo-500 focus:outline-none focus:bg-indigo-500",
|
||||||
|
icons::icon_7 {}
|
||||||
|
}
|
||||||
|
div {
|
||||||
|
class: "absolute right-0 z-20 w-48 mt-2 overflow-hidden bg-white rounded-md shadow-xl dark:bg-gray-700",
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Paginations
|
||||||
|
div {
|
||||||
|
class: "mt-8",
|
||||||
|
h4 {
|
||||||
|
class: "text-gray-600",
|
||||||
|
"Paginations"
|
||||||
|
}
|
||||||
|
div {
|
||||||
|
class: "mt-4",
|
||||||
|
div {
|
||||||
|
class: "flex px-4 py-4 overflow-x-auto bg-white rounded-md",
|
||||||
|
div {
|
||||||
|
class: "flex mr-4 rounded",
|
||||||
|
a {
|
||||||
|
class: "px-3 py-2 ml-0 leading-tight text-indigo-700 bg-white border border-r-0 border-gray-200 rounded-l hover:bg-indigo-500 hover:text-white",
|
||||||
|
href: "#",span {
|
||||||
|
"Previous"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
a {
|
||||||
|
class: "px-3 py-2 leading-tight text-indigo-700 bg-white border border-r-0 border-gray-200 hover:bg-indigo-500 hover:text-white",
|
||||||
|
href: "#",span {
|
||||||
|
"1"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
a {
|
||||||
|
class: "px-3 py-2 leading-tight text-indigo-700 bg-white border border-r-0 border-gray-200 hover:bg-indigo-500 hover:text-white",
|
||||||
|
href: "#",span {
|
||||||
|
"2"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
a {
|
||||||
|
class: "px-3 py-2 leading-tight text-indigo-700 bg-white border border-r-0 border-gray-200 hover:bg-indigo-500 hover:text-white",
|
||||||
|
href: "#",span {
|
||||||
|
"3"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
a {
|
||||||
|
class: "px-3 py-2 leading-tight text-indigo-700 bg-white border border-gray-200 rounded-r hover:bg-indigo-500 hover:text-white",
|
||||||
|
href: "#",span {
|
||||||
|
"Next"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
mod icons{
|
||||||
|
use dioxus::prelude::*;
|
||||||
|
use dioxus_html_macro::html;
|
||||||
|
|
||||||
|
pub fn icon_1(cx: Scope)->Element{
|
||||||
|
cx.render(html!{
|
||||||
|
<svg
|
||||||
|
class="w-6 h-6 text-white fill-current"
|
||||||
|
view_box="0 0 40 40"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M20 3.33331C10.8 3.33331 3.33337 10.8 3.33337 20C3.33337 29.2 10.8 36.6666 20 36.6666C29.2 36.6666 36.6667 29.2 36.6667 20C36.6667 10.8 29.2 3.33331 20 3.33331ZM16.6667 28.3333L8.33337 20L10.6834 17.65L16.6667 23.6166L29.3167 10.9666L31.6667 13.3333L16.6667 28.3333Z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn icon_2(cx: Scope)->Element{
|
||||||
|
cx.render(html!{
|
||||||
|
<svg
|
||||||
|
class="w-6 h-6 text-white fill-current"
|
||||||
|
view_box="0 0 40 40"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M20 3.33331C10.8 3.33331 3.33337 10.8 3.33337 20C3.33337 29.2 10.8 36.6666 20 36.6666C29.2 36.6666 36.6667 29.2 36.6667 20C36.6667 10.8 29.2 3.33331 20 3.33331ZM21.6667 28.3333H18.3334V25H21.6667V28.3333ZM21.6667 21.6666H18.3334V11.6666H21.6667V21.6666Z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn icon_3(cx: Scope)->Element{
|
||||||
|
cx.render(html!{
|
||||||
|
<svg
|
||||||
|
class="w-6 h-6 text-white fill-current"
|
||||||
|
view_box="0 0 40 40"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M20 3.33331C10.8 3.33331 3.33337 10.8 3.33337 20C3.33337 29.2 10.8 36.6666 20 36.6666C29.2 36.6666 36.6667 29.2 36.6667 20C36.6667 10.8 29.2 3.33331 20 3.33331ZM21.6667 28.3333H18.3334V25H21.6667V28.3333ZM21.6667 21.6666H18.3334V11.6666H21.6667V21.6666Z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn icon_4(cx: Scope)->Element{
|
||||||
|
cx.render(html!{
|
||||||
|
<svg
|
||||||
|
class="w-6 h-6 text-white fill-current"
|
||||||
|
view_box="0 0 40 40"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M20 3.36667C10.8167 3.36667 3.3667 10.8167 3.3667 20C3.3667 29.1833 10.8167 36.6333 20 36.6333C29.1834 36.6333 36.6334 29.1833 36.6334 20C36.6334 10.8167 29.1834 3.36667 20 3.36667ZM19.1334 33.3333V22.9H13.3334L21.6667 6.66667V17.1H27.25L19.1334 33.3333Z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn icon_5(cx: Scope)->Element{
|
||||||
|
cx.render(html!{
|
||||||
|
<svg class="w-5 h-5 text-gray-500" view_box="0 0 24 24" fill="none">
|
||||||
|
<path
|
||||||
|
d="M21 21L15 15M17 10C17 13.866 13.866 17 10 17C6.13401 17 3 13.866 3 10C3 6.13401 6.13401 3 10 3C13.866 3 17 6.13401 17 10Z"
|
||||||
|
stroke="currentColor"
|
||||||
|
stroke_width="2"
|
||||||
|
stroke_linecap="round"
|
||||||
|
stroke_linejoin="round"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn icon_6(cx: Scope)->Element{
|
||||||
|
cx.render(html!{
|
||||||
|
<svg class="w-5 h-5 mx-1" xmlns="http://www.w3.org/2000/svg"
|
||||||
|
view_box="0 0 20 20" fill="currentColor">
|
||||||
|
<path fill_rule="evenodd" d="M4 2a1 1 0 011 1v2.101a7.002 7.002 0 0111.601 2.566 1 1 0 11-1.885.666A5.002 5.002 0 005.999 7H9a1 1 0 010 2H4a1 1 0 01-1-1V3a1 1 0 011-1zm.008 9.057a1 1 0 011.276.61A5.002 5.002 0 0014.001 13H11a1 1 0 110-2h5a1 1 0 011 1v5a1 1 0 11-2 0v-2.101a7.002 7.002 0 01-11.601-2.566 1 1 0 01.61-1.276z"
|
||||||
|
clip_rule="evenodd" />
|
||||||
|
</svg>
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn icon_7(cx: Scope)->Element{
|
||||||
|
cx.render(html!{
|
||||||
|
<svg class="w-6 h-6 text-white" xmlns="http://www.w3.org/2000/svg" fill="none" view_box="0 0 24 24" stroke="currentColor">
|
||||||
|
<path stroke_linecap="round" stroke_linejoin="round" stroke_width="2"
|
||||||
|
d="M5 12h.01M12 12h.01M19 12h.01M6 12a1 1 0 11-2 0 1 1 0 012 0zm7 0a1 1 0 11-2 0 1 1 0 012 0zm7 0a1 1 0 11-2 0 1 1 0 012 0z" />
|
||||||
|
</svg>
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
BIN
static/favicon.ico
Normal file
BIN
static/favicon.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.2 KiB |
BIN
static/screenshot.jpg
Normal file
BIN
static/screenshot.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 95 KiB |
18
tailwind.config.js
Normal file
18
tailwind.config.js
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
/** @type {import('tailwindcss').Config} */
|
||||||
|
const defaultTheme = require('tailwindcss/defaultTheme')
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
content: ["./src/**/*.{rs,html}"],
|
||||||
|
theme: {
|
||||||
|
extend: {
|
||||||
|
fontFamily: {
|
||||||
|
sans: ['Inter var', ...defaultTheme.fontFamily.sans],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
plugins: [
|
||||||
|
require('@tailwindcss/forms'),
|
||||||
|
require('@tailwindcss/typography'),
|
||||||
|
require('@tailwindcss/aspect-ratio'),
|
||||||
|
],
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user