From 88958d149e5b23372a4fa71cc911287e0877eaee Mon Sep 17 00:00:00 2001 From: xeovalyte Date: Thu, 6 Jun 2024 11:58:01 +0200 Subject: [PATCH] Added modpack creation screen --- Cargo.lock | 239 +++++++++++++++++++++- Cargo.toml | 1 + assets/tailwind.css | 264 ++++++++++++++++++++++++- src/components.rs | 2 + src/components/home.rs | 4 +- src/components/layout.rs | 2 +- src/components/layout/authenticated.rs | 37 ++++ src/components/layout/navbar.rs | 23 --- src/components/modpacks.rs | 11 ++ src/components/new.rs | 53 +++++ src/main.rs | 17 +- src/modrinth.rs | 1 + src/modrinth/tags.rs | 1 + src/modrinth/tags/game_versions.rs | 15 ++ 14 files changed, 632 insertions(+), 38 deletions(-) create mode 100644 src/components/layout/authenticated.rs delete mode 100644 src/components/layout/navbar.rs create mode 100644 src/components/modpacks.rs create mode 100644 src/components/new.rs create mode 100644 src/modrinth.rs create mode 100644 src/modrinth/tags.rs create mode 100644 src/modrinth/tags/game_versions.rs diff --git a/Cargo.lock b/Cargo.lock index 9baf424..921d9f0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1587,6 +1587,21 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" +[[package]] +name = "foreign-types" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" +dependencies = [ + "foreign-types-shared", +] + +[[package]] +name = "foreign-types-shared" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" + [[package]] name = "form_urlencoded" version = "1.2.1" @@ -2067,6 +2082,25 @@ dependencies = [ "tracing", ] +[[package]] +name = "h2" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa82e28a107a8cc405f0839610bdc9b15f1e25ec7d696aa5cf173edbcb1486ab" +dependencies = [ + "atomic-waker", + "bytes", + "fnv", + "futures-core", + "futures-sink", + "http 1.1.0", + "indexmap 2.2.6", + "slab", + "tokio", + "tokio-util", + "tracing", +] + [[package]] name = "half" version = "2.4.1" @@ -2236,7 +2270,7 @@ dependencies = [ "futures-channel", "futures-core", "futures-util", - "h2", + "h2 0.3.26", "http 0.2.12", "http-body 0.4.6", "httparse", @@ -2259,6 +2293,7 @@ dependencies = [ "bytes", "futures-channel", "futures-util", + "h2 0.4.5", "http 1.1.0", "http-body 1.0.0", "httparse", @@ -2267,6 +2302,7 @@ dependencies = [ "pin-project-lite", "smallvec", "tokio", + "want", ] [[package]] @@ -2283,6 +2319,22 @@ dependencies = [ "tokio-rustls", ] +[[package]] +name = "hyper-tls" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0" +dependencies = [ + "bytes", + "http-body-util", + "hyper 1.3.1", + "hyper-util", + "native-tls", + "tokio", + "tokio-native-tls", + "tower-service", +] + [[package]] name = "hyper-util" version = "0.1.5" @@ -2290,12 +2342,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7b875924a60b96e5d7b9ae7b066540b1dd1cbd90d1828f54c92e02a283351c56" dependencies = [ "bytes", + "futures-channel", "futures-util", "http 1.1.0", "http-body 1.0.0", "hyper 1.3.1", "pin-project-lite", + "socket2", "tokio", + "tower", + "tower-service", + "tracing", ] [[package]] @@ -2802,6 +2859,23 @@ dependencies = [ "getrandom", ] +[[package]] +name = "native-tls" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8614eb2c83d59d1c8cc974dd3f920198647674a0a035e1af1fa58707e317466" +dependencies = [ + "libc", + "log", + "openssl", + "openssl-probe", + "openssl-sys", + "schannel", + "security-framework", + "security-framework-sys", + "tempfile", +] + [[package]] name = "ndarray" version = "0.15.6" @@ -2993,6 +3067,50 @@ version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" +[[package]] +name = "openssl" +version = "0.10.64" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95a0481286a310808298130d22dd1fef0fa571e05a8f44ec801801e84b216b1f" +dependencies = [ + "bitflags 2.5.0", + "cfg-if", + "foreign-types", + "libc", + "once_cell", + "openssl-macros", + "openssl-sys", +] + +[[package]] +name = "openssl-macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.66", +] + +[[package]] +name = "openssl-probe" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" + +[[package]] +name = "openssl-sys" +version = "0.9.102" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c597637d56fbc83893a35eb0dd04b2b8e7a50c91e64e9493e398b5df4fb45fa2" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] + [[package]] name = "ordered-float" version = "2.10.1" @@ -3502,7 +3620,7 @@ dependencies = [ "encoding_rs", "futures-core", "futures-util", - "h2", + "h2 0.3.26", "http 0.2.12", "http-body 0.4.6", "hyper 0.14.29", @@ -3516,7 +3634,7 @@ dependencies = [ "percent-encoding", "pin-project-lite", "rustls", - "rustls-pemfile", + "rustls-pemfile 1.0.4", "serde", "serde_json", "serde_urlencoded", @@ -3532,7 +3650,49 @@ dependencies = [ "wasm-streams", "web-sys", "webpki-roots", - "winreg", + "winreg 0.50.0", +] + +[[package]] +name = "reqwest" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "566cafdd92868e0939d3fb961bd0dc25fcfaaed179291093b3d43e6b3150ea10" +dependencies = [ + "base64 0.22.1", + "bytes", + "encoding_rs", + "futures-core", + "futures-util", + "h2 0.4.5", + "http 1.1.0", + "http-body 1.0.0", + "http-body-util", + "hyper 1.3.1", + "hyper-tls", + "hyper-util", + "ipnet", + "js-sys", + "log", + "mime", + "native-tls", + "once_cell", + "percent-encoding", + "pin-project-lite", + "rustls-pemfile 2.1.2", + "serde", + "serde_json", + "serde_urlencoded", + "sync_wrapper 0.1.2", + "system-configuration", + "tokio", + "tokio-native-tls", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "winreg 0.52.0", ] [[package]] @@ -3795,6 +3955,22 @@ dependencies = [ "base64 0.21.7", ] +[[package]] +name = "rustls-pemfile" +version = "2.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29993a25686778eb88d4189742cd713c9bce943bc54251a33509dc63cbacf73d" +dependencies = [ + "base64 0.22.1", + "rustls-pki-types", +] + +[[package]] +name = "rustls-pki-types" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "976295e77ce332211c0d24d92c0e83e50f5c5f046d11082cea19f3df13a3562d" + [[package]] name = "rustls-webpki" version = "0.101.7" @@ -3835,6 +4011,15 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "schannel" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbc91545643bcf3a0bbb6569265615222618bdf33ce4ffbbd13c4bbd4c093534" +dependencies = [ + "windows-sys 0.52.0", +] + [[package]] name = "scopeguard" version = "1.2.0" @@ -3869,6 +4054,29 @@ version = "4.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1c107b6f4780854c8b126e228ea8869f4d7b71260f962fefb57b996b8959ba6b" +[[package]] +name = "security-framework" +version = "2.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c627723fd09706bacdb5cf41499e95098555af3c3c29d014dc3c458ef6be11c0" +dependencies = [ + "bitflags 2.5.0", + "core-foundation", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework-sys" +version = "2.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "317936bbbd05227752583946b9e66d7ce3b489f84e11a94a510b4437fef407d7" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "semver" version = "1.0.23" @@ -4375,7 +4583,7 @@ dependencies = [ "once_cell", "path-clean", "pharos", - "reqwest", + "reqwest 0.11.27", "revision", "ring 0.17.8", "rust_decimal", @@ -4793,6 +5001,16 @@ dependencies = [ "syn 2.0.66", ] +[[package]] +name = "tokio-native-tls" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" +dependencies = [ + "native-tls", + "tokio", +] + [[package]] name = "tokio-rustls" version = "0.24.1" @@ -5556,6 +5774,16 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "winreg" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a277a57398d4bfa075df44f501a17cfdf8542d224f0d36095a2adc7aee4ef0a5" +dependencies = [ + "cfg-if", + "windows-sys 0.48.0", +] + [[package]] name = "ws_stream_wasm" version = "0.7.4" @@ -5594,6 +5822,7 @@ dependencies = [ "dioxus", "dioxus-logger", "once_cell", + "reqwest 0.12.4", "serde", "surrealdb", "tokio", diff --git a/Cargo.toml b/Cargo.toml index b201c71..1ff4d23 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,6 +17,7 @@ tokio = { version = "1.38.0", features = [ "macros", "rt-multi-thread" ], option argon2 = { version = "0.5.3", optional = true } axum = { version = "0.7.5", optional = true } axum-extra = { version = "0.9.3", features = [ "cookie" ], optional = true} +reqwest = { version = "0.12", features = ["json"] } # Debug tracing = "0.1.40" diff --git a/assets/tailwind.css b/assets/tailwind.css index 00f99cd..5495a1a 100644 --- a/assets/tailwind.css +++ b/assets/tailwind.css @@ -1,5 +1,5 @@ /* -! tailwindcss v3.4.3 | MIT License | https://tailwindcss.com +! tailwindcss v3.4.4 | MIT License | https://tailwindcss.com */ /* @@ -903,7 +903,33 @@ html { color: var(--fallback-nc,oklch(var(--nc)/var(--tw-text-opacity))); } +.checkbox { + flex-shrink: 0; + --chkbg: var(--fallback-bc,oklch(var(--bc)/1)); + --chkfg: var(--fallback-b1,oklch(var(--b1)/1)); + height: 1.5rem; + width: 1.5rem; + cursor: pointer; + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; + border-radius: var(--rounded-btn, 0.5rem); + border-width: 1px; + border-color: var(--fallback-bc,oklch(var(--bc)/var(--tw-border-opacity))); + --tw-border-opacity: 0.2; +} + @media (hover: hover) { + .btm-nav > *.disabled:hover, + .btm-nav > *[disabled]:hover { + pointer-events: none; + --tw-border-opacity: 0; + background-color: var(--fallback-n,oklch(var(--n)/var(--tw-bg-opacity))); + --tw-bg-opacity: 0.1; + color: var(--fallback-bc,oklch(var(--bc)/var(--tw-text-opacity))); + --tw-text-opacity: 0.2; + } + .btn:hover { --tw-border-opacity: 1; border-color: var(--fallback-b3,oklch(var(--b3)/var(--tw-border-opacity))); @@ -1060,6 +1086,14 @@ html { text-decoration-line: none; } +.menu li.disabled { + cursor: not-allowed; + -webkit-user-select: none; + -moz-user-select: none; + user-select: none; + color: var(--fallback-bc,oklch(var(--bc)/0.3)); +} + .navbar { display: flex; align-items: center; @@ -1073,6 +1107,40 @@ html { align-items: center; } +.select { + display: inline-flex; + cursor: pointer; + -webkit-user-select: none; + -moz-user-select: none; + user-select: none; + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; + height: 3rem; + min-height: 3rem; + padding-left: 1rem; + padding-right: 2.5rem; + font-size: 0.875rem; + line-height: 1.25rem; + line-height: 2; + border-radius: var(--rounded-btn, 0.5rem); + border-width: 1px; + border-color: transparent; + --tw-bg-opacity: 1; + background-color: var(--fallback-b1,oklch(var(--b1)/var(--tw-bg-opacity))); + background-image: linear-gradient(45deg, transparent 50%, currentColor 50%), + linear-gradient(135deg, currentColor 50%, transparent 50%); + background-position: calc(100% - 20px) calc(1px + 50%), + calc(100% - 16.1px) calc(1px + 50%); + background-size: 4px 4px, + 4px 4px; + background-repeat: no-repeat; +} + +.select[multiple] { + height: auto; +} + .tabs { display: grid; align-items: flex-end; @@ -1170,6 +1238,16 @@ input.tab:checked + .tab-content, background-color: var(--fallback-b1,oklch(var(--b1)/var(--tw-bg-opacity))); } +.btm-nav > *.disabled, + .btm-nav > *[disabled] { + pointer-events: none; + --tw-border-opacity: 0; + background-color: var(--fallback-n,oklch(var(--n)/var(--tw-bg-opacity))); + --tw-bg-opacity: 0.1; + color: var(--fallback-bc,oklch(var(--bc)/var(--tw-text-opacity))); + --tw-text-opacity: 0.2; +} + .btm-nav > * .label { font-size: 1rem; line-height: 1.5rem; @@ -1337,6 +1415,54 @@ input.tab:checked + .tab-content, border-radius: inherit; } +.checkbox:focus { + box-shadow: none; +} + +.checkbox:focus-visible { + outline-style: solid; + outline-width: 2px; + outline-offset: 2px; + outline-color: var(--fallback-bc,oklch(var(--bc)/1)); +} + +.checkbox:disabled { + border-width: 0px; + cursor: not-allowed; + border-color: transparent; + --tw-bg-opacity: 1; + background-color: var(--fallback-bc,oklch(var(--bc)/var(--tw-bg-opacity))); + opacity: 0.2; +} + +.checkbox:checked, + .checkbox[aria-checked="true"] { + background-repeat: no-repeat; + animation: checkmark var(--animation-input, 0.2s) ease-out; + background-color: var(--chkbg); + background-image: linear-gradient(-45deg, transparent 65%, var(--chkbg) 65.99%), + linear-gradient(45deg, transparent 75%, var(--chkbg) 75.99%), + linear-gradient(-45deg, var(--chkbg) 40%, transparent 40.99%), + linear-gradient( + 45deg, + var(--chkbg) 30%, + var(--chkfg) 30.99%, + var(--chkfg) 40%, + transparent 40.99% + ), + linear-gradient(-45deg, var(--chkfg) 50%, var(--chkbg) 50.99%); +} + +.checkbox:indeterminate { + --tw-bg-opacity: 1; + background-color: var(--fallback-bc,oklch(var(--bc)/var(--tw-bg-opacity))); + background-repeat: no-repeat; + animation: checkmark var(--animation-input, 0.2s) ease-out; + background-image: linear-gradient(90deg, transparent 80%, var(--chkbg) 80%), + linear-gradient(-90deg, transparent 80%, var(--chkbg) 80%), + linear-gradient(0deg, var(--chkbg) 43%, var(--chkfg) 43%, var(--chkfg) 57%, var(--chkbg) 57%); +} + @keyframes checkmark { 0% { background-position-y: 5px; @@ -1526,6 +1652,54 @@ input.tab:checked + .tab-content, } } +.select-bordered { + border-color: var(--fallback-bc,oklch(var(--bc)/0.2)); +} + +.select:focus { + box-shadow: none; + border-color: var(--fallback-bc,oklch(var(--bc)/0.2)); + outline-style: solid; + outline-width: 2px; + outline-offset: 2px; + outline-color: var(--fallback-bc,oklch(var(--bc)/0.2)); +} + +.select-disabled, + .select:disabled, + .select[disabled] { + cursor: not-allowed; + --tw-border-opacity: 1; + border-color: var(--fallback-b2,oklch(var(--b2)/var(--tw-border-opacity))); + --tw-bg-opacity: 1; + background-color: var(--fallback-b2,oklch(var(--b2)/var(--tw-bg-opacity))); + color: var(--fallback-bc,oklch(var(--bc)/0.4)); +} + +.select-disabled::-moz-placeholder, .select:disabled::-moz-placeholder, .select[disabled]::-moz-placeholder { + color: var(--fallback-bc,oklch(var(--bc)/var(--tw-placeholder-opacity))); + --tw-placeholder-opacity: 0.2; +} + +.select-disabled::placeholder, + .select:disabled::placeholder, + .select[disabled]::placeholder { + color: var(--fallback-bc,oklch(var(--bc)/var(--tw-placeholder-opacity))); + --tw-placeholder-opacity: 0.2; +} + +.select-multiple, + .select[multiple], + .select[size].select:not([size="1"]) { + background-image: none; + padding-right: 1rem; +} + +[dir="rtl"] .select { + background-position: calc(0% + 12px) calc(1px + 50%), + calc(0% + 16px) calc(1px + 50%); +} + @keyframes skeleton { from { background-position: 150%; @@ -1721,6 +1895,32 @@ input.tab:checked + .tab-content, } } +.btn-sm { + height: 2rem; + min-height: 2rem; + padding-left: 0.75rem; + padding-right: 0.75rem; + font-size: 0.875rem; +} + +.btn-square:where(.btn-sm) { + height: 2rem; + width: 2rem; + padding: 0px; +} + +.btn-circle:where(.btn-sm) { + height: 2rem; + width: 2rem; + border-radius: 9999px; + padding: 0px; +} + +[type="checkbox"].checkbox-sm { + height: 1.25rem; + width: 1.25rem; +} + .tabs-md :where(.tab) { height: 2rem; font-size: 0.875rem; @@ -1780,6 +1980,26 @@ input.tab:checked + .tab-content, margin-top: 1.5rem; } +.mt-10 { + margin-top: 2.5rem; +} + +.mt-5 { + margin-top: 1.25rem; +} + +.mt-16 { + margin-top: 4rem; +} + +.mt-8 { + margin-top: 2rem; +} + +.flex { + display: flex; +} + .table { display: table; } @@ -1796,6 +2016,18 @@ input.tab:checked + .tab-content, max-width: 32rem; } +.max-w-4xl { + max-width: 56rem; +} + +.max-w-md { + max-width: 28rem; +} + +.max-w-xl { + max-width: 36rem; +} + .flex-1 { flex: 1 1 0%; } @@ -1804,6 +2036,22 @@ input.tab:checked + .tab-content, flex: none; } +.justify-start { + justify-content: flex-start; +} + +.gap-5 { + gap: 1.25rem; +} + +.gap-2 { + gap: 0.5rem; +} + +.gap-1 { + gap: 0.25rem; +} + .bg-base-100 { --tw-bg-opacity: 1; background-color: var(--fallback-b1,oklch(var(--b1)/var(--tw-bg-opacity))); @@ -1829,6 +2077,11 @@ input.tab:checked + .tab-content, padding-bottom: 1.5rem; } +.px-2 { + padding-left: 0.5rem; + padding-right: 0.5rem; +} + .pt-40 { padding-top: 10rem; } @@ -1847,6 +2100,11 @@ input.tab:checked + .tab-content, line-height: 1.75rem; } +.text-2xl { + font-size: 1.5rem; + line-height: 2rem; +} + .font-bold { font-weight: 700; } @@ -1855,4 +2113,8 @@ input.tab:checked + .tab-content, --tw-shadow: 0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1); --tw-shadow-colored: 0 20px 25px -5px var(--tw-shadow-color), 0 8px 10px -6px var(--tw-shadow-color); box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow); +} + +.filter { + filter: var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow); } \ No newline at end of file diff --git a/src/components.rs b/src/components.rs index 5ffbe80..cae65f0 100644 --- a/src/components.rs +++ b/src/components.rs @@ -1,3 +1,5 @@ pub mod auth; pub mod home; pub mod layout; +pub mod modpacks; +pub mod new; diff --git a/src/components/home.rs b/src/components/home.rs index a9f238b..7d84cc7 100644 --- a/src/components/home.rs +++ b/src/components/home.rs @@ -1,5 +1,7 @@ use dioxus::prelude::*; +use crate::Route; + #[component] pub fn Home() -> Element { rsx! { @@ -11,7 +13,7 @@ pub fn Home() -> Element { class: "max-w-2xl", h1 { class: "text-5xl font-bold", "Xeovalyte's Minecraft Mod Manager" }, p { class: "py-6", "XVMCMM is a mod manager for the modrinth website. Create, update and export your modpacks with ease to the .mrpack format." }, - button { class: "btn btn-primary", "Get Started" }, + Link { class: "btn btn-primary", to: Route::Modpacks {}, "Get Started" }, } } } diff --git a/src/components/layout.rs b/src/components/layout.rs index 302260f..3aaf49e 100644 --- a/src/components/layout.rs +++ b/src/components/layout.rs @@ -1 +1 @@ -pub mod navbar; +pub mod authenticated; diff --git a/src/components/layout/authenticated.rs b/src/components/layout/authenticated.rs new file mode 100644 index 0000000..77eeda9 --- /dev/null +++ b/src/components/layout/authenticated.rs @@ -0,0 +1,37 @@ +use crate::Route; +use dioxus::prelude::*; + +use crate::components::auth::Auth; + +#[component] +pub fn Authenticated() -> Element { + let user = use_context::(); + + rsx! { + match &*user.read_unchecked() { + Some(Ok(_)) => rsx! { + div { + class: "navbar bg-base-200", + div { + class: "flex-1", + Link { class: "btn btn-ghost text-xl", to: Route::Home {}, "XVMCMM" }, + } + div { + class: "flex-none", + ul { + class: "px-1 py-1", + li { Link { class: "btn btn-primary", to: Route::New {}, "Create" } }, + } + } + } + Outlet:: {} + }, + Some(Err(_)) => rsx! { + Auth {}, + }, + None => rsx! { + div { "Loading..." } + } + } + } +} diff --git a/src/components/layout/navbar.rs b/src/components/layout/navbar.rs deleted file mode 100644 index 3eb5313..0000000 --- a/src/components/layout/navbar.rs +++ /dev/null @@ -1,23 +0,0 @@ -use crate::Route; -use dioxus::prelude::*; - -#[component] -pub fn Navbar() -> Element { - rsx! { - div { - class: "navbar bg-base-200", - div { - class: "flex-1", - Link { class: "btn btn-ghost text-xl", to: Route::Home {}, "XVMCMM" }, - } - div { - class: "flex-none", - ul { - class: "px-1 py-1", - li { Link { class: "btn btn-primary", to: Route::Auth {}, "Sign In" } }, - } - } - } - Outlet:: {} - } -} diff --git a/src/components/modpacks.rs b/src/components/modpacks.rs new file mode 100644 index 0000000..cf8f83a --- /dev/null +++ b/src/components/modpacks.rs @@ -0,0 +1,11 @@ +use dioxus::prelude::*; + +#[component] +pub fn Modpacks() -> Element { + rsx! { + div { + class: "max-w-4xl px-2 w-full mx-auto", + h2 { class: "text-2xl font-bold mt-10", "Modpacks" } + } + } +} diff --git a/src/components/new.rs b/src/components/new.rs new file mode 100644 index 0000000..bcb0460 --- /dev/null +++ b/src/components/new.rs @@ -0,0 +1,53 @@ +use dioxus::prelude::*; + +use crate::modrinth::tags::game_versions::{get_game_versions, GameVersion}; + +#[component] +pub fn New() -> Element { + let game_versions = use_resource(|| async move { + let response = get_game_versions().await; + + match response { + Ok(r) => Ok(r + .into_iter() + .filter(|v| v.major == true) + .collect::>()), + Err(err) => Err(err), + } + }); + + rsx! { + div { + class: "max-w-md w-full mx-auto", + h2 { class: "text-2xl font-bold mt-20", "Create a new modpack" } + form { + class: "mt-10", + input { r#type: "text", placeholder: "Name", class: "input input-bordered w-full" } + div { + class: "flex gap-5 mt-6", + select { + class: "select select-bordered w-full", + option { disabled: true, selected: true, "Minecraft Version" }, + match &*game_versions.read_unchecked() { + Some(Ok(response)) => rsx! { + for game_version in response { + option { "{game_version.version}" } + } + }, + _ => rsx! { option { disabled: true, "Loading..." } } + } + } + select { + class: "select select-bordered", + option { disabled: true, selected: true, "Modloader" }, + option { "Fabric" }, + option { "Quilt" }, + option { "Forge" }, + option { "Neoforge" }, + } + } + button { class: "btn btn-primary mt-10 w-full", "Submit" } + } + } + } +} diff --git a/src/main.rs b/src/main.rs index 2f7434c..3c4593a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,26 +1,29 @@ #![allow(non_snake_case)] mod components; - +mod modrinth; mod server; use dioxus::prelude::*; use tracing::{info, Level}; -use components::auth::Auth; use components::home::Home; -use components::layout::navbar::Navbar; +use components::layout::authenticated::Authenticated; +use components::modpacks::Modpacks; +use components::new::New; use server::auth; pub type UserState = Resource>; #[derive(Clone, Routable)] pub enum Route { - #[layout(Navbar)] + #[layout(Authenticated)] + #[route("/modpacks")] + Modpacks {}, + #[route("/new")] + New {}, + #[end_layout] #[route("/")] Home {}, - - #[route("/auth")] - Auth {}, } fn main() { diff --git a/src/modrinth.rs b/src/modrinth.rs new file mode 100644 index 0000000..cb4849d --- /dev/null +++ b/src/modrinth.rs @@ -0,0 +1 @@ +pub mod tags; diff --git a/src/modrinth/tags.rs b/src/modrinth/tags.rs new file mode 100644 index 0000000..c507af5 --- /dev/null +++ b/src/modrinth/tags.rs @@ -0,0 +1 @@ +pub mod game_versions; diff --git a/src/modrinth/tags/game_versions.rs b/src/modrinth/tags/game_versions.rs new file mode 100644 index 0000000..f9e3349 --- /dev/null +++ b/src/modrinth/tags/game_versions.rs @@ -0,0 +1,15 @@ +use serde::Deserialize; + +#[derive(Deserialize)] +pub struct GameVersion { + pub version: String, + pub version_type: String, + pub date: String, + pub major: bool, +} + +pub async fn get_game_versions() -> Result, reqwest::Error> { + let response = reqwest::get("https://api.modrinth.com/v2/tag/game_version").await?; + + response.json::>().await +}