Compare commits
2 Commits
ec195dfbf7
...
a75df84dcb
Author | SHA1 | Date | |
---|---|---|---|
a75df84dcb | |||
fdd029ffd7 |
2359
Cargo.lock
generated
2359
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
32
Cargo.toml
32
Cargo.toml
@ -7,28 +7,40 @@ edition = "2021"
|
|||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
serde = { version = "1.0.197", features = ["derive"] }
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
|
|
||||||
dioxus = { version = "0.5", features = ["fullstack", "router"] }
|
dioxus = { version = "0.6", features = ["fullstack", "router"] }
|
||||||
web-sys = { version = "0.3.70", features = ["Window", "Location"] }
|
dioxus-cli-config = { version = "0.6", optional = true }
|
||||||
|
web-sys = { version = "0.3", features = ["Window", "Location"] }
|
||||||
|
|
||||||
tokio = { version = "1.38", features = ["macros", "rt-multi-thread"], optional = true }
|
tokio = { version = "1.42", features = ["macros", "rt-multi-thread"], optional = true }
|
||||||
axum = { version = "0.7", optional = true }
|
axum = { version = "0.7", optional = true }
|
||||||
axum-extra = { version = "0.9", features = ["cookie"], optional = true }
|
axum-extra = { version = "0.9", features = ["cookie"], optional = true }
|
||||||
time = { version = "0.3", optional = true }
|
time = { version = "0.3", optional = true }
|
||||||
once_cell = { version = "1.19", optional = true }
|
once_cell = { version = "1.20", optional = true }
|
||||||
surrealdb = { version = "2.0", optional = true }
|
surrealdb = { version = "2.1", optional = true }
|
||||||
thiserror = { version = "1.0" }
|
thiserror = { version = "2.0" }
|
||||||
strum = { version = "0.26", features = ["derive"] }
|
strum = { version = "0.26", features = ["derive"] }
|
||||||
|
|
||||||
csv = { version = "1.3", optional = true }
|
csv = { version = "1.3", optional = true }
|
||||||
|
|
||||||
# Debug
|
# Debug
|
||||||
tracing = "0.1"
|
tracing = "0.1"
|
||||||
dioxus-logger = "0.5"
|
manganis = "0.6"
|
||||||
manganis = "0.2"
|
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = []
|
default = []
|
||||||
server = [ "dioxus/axum", "tokio", "axum", "axum-extra", "time", "once_cell", "surrealdb", "csv" ]
|
server = [ "dioxus/server", "dioxus-cli-config", "tokio", "axum", "axum-extra", "time", "once_cell", "surrealdb", "csv" ]
|
||||||
web = ["dioxus/web"]
|
web = ["dioxus/web"]
|
||||||
|
|
||||||
|
[profile]
|
||||||
|
|
||||||
|
[profile.wasm-dev]
|
||||||
|
inherits = "dev"
|
||||||
|
opt-level = 1
|
||||||
|
|
||||||
|
[profile.server-dev]
|
||||||
|
inherits = "dev"
|
||||||
|
|
||||||
|
[profile.android-dev]
|
||||||
|
inherits = "dev"
|
||||||
|
@ -3352,6 +3352,10 @@ details.collapse summary::-webkit-details-marker {
|
|||||||
display: contents;
|
display: contents;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.hidden {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
.size-6 {
|
.size-6 {
|
||||||
width: 1.5rem;
|
width: 1.5rem;
|
||||||
height: 1.5rem;
|
height: 1.5rem;
|
||||||
@ -3392,12 +3396,12 @@ details.collapse summary::-webkit-details-marker {
|
|||||||
min-height: 4rem;
|
min-height: 4rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.w-1\/2 {
|
.w-1\/3 {
|
||||||
width: 50%;
|
width: 33.333333%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.w-1\/4 {
|
.w-2\/3 {
|
||||||
width: 25%;
|
width: 66.666667%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.w-80 {
|
.w-80 {
|
||||||
|
@ -2,8 +2,7 @@ use crate::util::model::{
|
|||||||
member::{Member, MembersMigration},
|
member::{Member, MembersMigration},
|
||||||
session::Session,
|
session::Session,
|
||||||
};
|
};
|
||||||
use dioxus::prelude::{dioxus_elements::FileEngine, *};
|
use dioxus::prelude::*;
|
||||||
use std::sync::Arc;
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct UploadedFile {
|
struct UploadedFile {
|
||||||
@ -31,12 +30,12 @@ pub fn Migration() -> Element {
|
|||||||
li { class: "step step-primary", "Uploaden" },
|
li { class: "step step-primary", "Uploaden" },
|
||||||
li {
|
li {
|
||||||
class: "step",
|
class: "step",
|
||||||
class: if let Steps::Verify | Steps::Done = *step.read() { { "step-primary" } },
|
class: if let Steps::Verify | Steps::Done = *step.read() { "step-primary" },
|
||||||
"Controleren"
|
"Controleren"
|
||||||
},
|
},
|
||||||
li {
|
li {
|
||||||
class: "step",
|
class: "step",
|
||||||
class: if let Steps::Done = *step.read() { { "step-primary" } },
|
class: if let Steps::Done = *step.read() { "step-primary" },
|
||||||
"Klaar"
|
"Klaar"
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -51,26 +50,23 @@ pub fn Migration() -> Element {
|
|||||||
|
|
||||||
#[component]
|
#[component]
|
||||||
fn Upload(step: Signal<Steps>, members_migration: Signal<(u16, MembersMigration)>) -> Element {
|
fn Upload(step: Signal<Steps>, members_migration: Signal<(u16, MembersMigration)>) -> Element {
|
||||||
let mut file_uploaded = use_signal(|| None);
|
let mut file_uploaded: Signal<Option<UploadedFile>> = use_signal(|| None);
|
||||||
|
|
||||||
let mut loading = use_signal(|| false);
|
let mut loading = use_signal(|| false);
|
||||||
|
|
||||||
let read_files = move |file_engine: Arc<dyn FileEngine>| async move {
|
|
||||||
let files = file_engine.files();
|
|
||||||
for file_name in &files {
|
|
||||||
if let Some(contents) = file_engine.read_file_to_string(file_name).await {
|
|
||||||
file_uploaded.set(Some(UploadedFile {
|
|
||||||
name: file_name.clone(),
|
|
||||||
contents,
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
let upload_files = move |evt: FormEvent| async move {
|
let upload_files = move |evt: FormEvent| async move {
|
||||||
if let Some(file_engine) = evt.files() {
|
// TODO: Uncomment after bugfix dioxus
|
||||||
read_files(file_engine).await;
|
// if let Some(file_engine) = &evt.files() {
|
||||||
}
|
// let files = file_engine.files();
|
||||||
|
// for file_name in &files {
|
||||||
|
// if let Some(file) = file_engine.read_file_to_string(file_name).await {
|
||||||
|
// file_uploaded.set(Some(UploadedFile {
|
||||||
|
// name: file_name.to_owned(),
|
||||||
|
// contents: file,
|
||||||
|
// }))
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
};
|
};
|
||||||
|
|
||||||
let sumbit = move |_evt: FormEvent| async move {
|
let sumbit = move |_evt: FormEvent| async move {
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
use crate::util::model::news::{Target, TargetKind};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
@ -49,27 +50,36 @@ pub fn NewsCreate() -> Element {
|
|||||||
li { class: "step step-primary", "Inhoud" },
|
li { class: "step step-primary", "Inhoud" },
|
||||||
li {
|
li {
|
||||||
class: "step",
|
class: "step",
|
||||||
class: if let Steps::Targets | Steps::Done | Steps::Verify = *step.read() { { "step-primary" } },
|
class: if let Steps::Targets | Steps::Done | Steps::Verify = *step.read() { "step-primary" },
|
||||||
"Naar"
|
"Naar"
|
||||||
}
|
}
|
||||||
li {
|
li {
|
||||||
class: "step",
|
class: "step",
|
||||||
class: if let Steps::Verify | Steps::Done = *step.read() { { "step-primary" } },
|
class: if let Steps::Verify | Steps::Done = *step.read() { "step-primary" },
|
||||||
"Controleren"
|
"Controleren"
|
||||||
}
|
}
|
||||||
li {
|
li {
|
||||||
class: "step",
|
class: "step",
|
||||||
class: if let Steps::Done = *step.read() { { "step-primary" } },
|
class: if let Steps::Done = *step.read() { "step-primary" },
|
||||||
"Klaar"
|
"Klaar"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
div {
|
div {
|
||||||
class: "flex flex-col gap-y-5",
|
class: "flex flex-col gap-y-5",
|
||||||
match *step.read() {
|
div {
|
||||||
Steps::Message => rsx! { Message { step: step, title: form.title, body: form.body } },
|
class: if let Steps::Message = *step.read() { "" } else { "hidden" },
|
||||||
Steps::Targets => rsx! { TargetSelect { step: step, targets: form.targets } },
|
Message {
|
||||||
Steps::Verify => rsx! { { } },
|
step: step,
|
||||||
Steps::Done => rsx! { { } },
|
title: form.title,
|
||||||
|
body: form.body,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
div {
|
||||||
|
class: if let Steps::Targets = *step.read() { "" } else { "hidden" },
|
||||||
|
TargetSelect {
|
||||||
|
step: step,
|
||||||
|
targets: form.targets,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -81,9 +91,6 @@ fn Message(step: Signal<Steps>, title: Signal<String>, body: Signal<String>) ->
|
|||||||
let submit = move |event: FormEvent| {
|
let submit = move |event: FormEvent| {
|
||||||
title.set(event.values()["title"].as_value());
|
title.set(event.values()["title"].as_value());
|
||||||
body.set(event.values()["body"].as_value());
|
body.set(event.values()["body"].as_value());
|
||||||
|
|
||||||
tracing::info!("{title}");
|
|
||||||
|
|
||||||
step.set(Steps::Targets);
|
step.set(Steps::Targets);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -101,7 +108,6 @@ fn Message(step: Signal<Steps>, title: Signal<String>, body: Signal<String>) ->
|
|||||||
r#type: "text",
|
r#type: "text",
|
||||||
required: true,
|
required: true,
|
||||||
name: "title",
|
name: "title",
|
||||||
value: "{title}",
|
|
||||||
class: "input input-bordered w-full",
|
class: "input input-bordered w-full",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -113,7 +119,6 @@ fn Message(step: Signal<Steps>, title: Signal<String>, body: Signal<String>) ->
|
|||||||
},
|
},
|
||||||
textarea {
|
textarea {
|
||||||
name: "body",
|
name: "body",
|
||||||
value: "{body}",
|
|
||||||
class: "textarea textarea-bordered w-full",
|
class: "textarea textarea-bordered w-full",
|
||||||
required: true,
|
required: true,
|
||||||
}
|
}
|
||||||
@ -130,39 +135,6 @@ fn Message(step: Signal<Steps>, title: Signal<String>, body: Signal<String>) ->
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(PartialEq, Clone, Copy, Debug)]
|
|
||||||
enum TargetKind {
|
|
||||||
None,
|
|
||||||
All,
|
|
||||||
Group,
|
|
||||||
Hourgroup,
|
|
||||||
Hour,
|
|
||||||
Member,
|
|
||||||
Account,
|
|
||||||
Day,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(PartialEq, Debug)]
|
|
||||||
struct Target {
|
|
||||||
kind: TargetKind,
|
|
||||||
value: String,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl TargetKind {
|
|
||||||
fn from_string(input: &str) -> Self {
|
|
||||||
match input {
|
|
||||||
"all" => Self::All,
|
|
||||||
"group" => Self::Group,
|
|
||||||
"hourgroup" => Self::Hourgroup,
|
|
||||||
"hour" => Self::Hour,
|
|
||||||
"member" => Self::Member,
|
|
||||||
"account" => Self::Account,
|
|
||||||
"day" => Self::Day,
|
|
||||||
_ => Self::None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[component]
|
#[component]
|
||||||
fn TargetSelect(step: Signal<Steps>, targets: Signal<HashMap<u32, Target>>) -> Element {
|
fn TargetSelect(step: Signal<Steps>, targets: Signal<HashMap<u32, Target>>) -> Element {
|
||||||
let mut target_id = use_signal(|| 1);
|
let mut target_id = use_signal(|| 1);
|
||||||
@ -172,12 +144,17 @@ fn TargetSelect(step: Signal<Steps>, targets: Signal<HashMap<u32, Target>>) -> E
|
|||||||
|
|
||||||
filtered_targets.sort_unstable();
|
filtered_targets.sort_unstable();
|
||||||
|
|
||||||
tracing::info!("targets updated");
|
|
||||||
|
|
||||||
filtered_targets
|
filtered_targets
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let submit = move |_| {
|
||||||
|
step.set(Steps::Verify);
|
||||||
|
};
|
||||||
|
|
||||||
rsx! {
|
rsx! {
|
||||||
|
form {
|
||||||
|
class: "w-full",
|
||||||
|
onsubmit: submit,
|
||||||
label {
|
label {
|
||||||
class: "form-control w-full",
|
class: "form-control w-full",
|
||||||
div {
|
div {
|
||||||
@ -207,6 +184,7 @@ fn TargetSelect(step: Signal<Steps>, targets: Signal<HashMap<u32, Target>>) -> E
|
|||||||
class: "w-full flex gap-x-3 justify-end",
|
class: "w-full flex gap-x-3 justify-end",
|
||||||
button {
|
button {
|
||||||
class: "btn",
|
class: "btn",
|
||||||
|
r#type: "button",
|
||||||
onclick: move |_| {
|
onclick: move |_| {
|
||||||
step.set(Steps::Message)
|
step.set(Steps::Message)
|
||||||
},
|
},
|
||||||
@ -214,32 +192,29 @@ fn TargetSelect(step: Signal<Steps>, targets: Signal<HashMap<u32, Target>>) -> E
|
|||||||
}
|
}
|
||||||
button {
|
button {
|
||||||
class: "btn btn-primary",
|
class: "btn btn-primary",
|
||||||
onclick: move |_| {
|
|
||||||
step.set(Steps::Verify)
|
|
||||||
},
|
|
||||||
"Volgende",
|
"Volgende",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[component]
|
#[component]
|
||||||
fn TargetEntry(mut targets: Signal<HashMap<u32, Target>>, id: u32) -> Element {
|
fn TargetEntry(mut targets: Signal<HashMap<u32, Target>>, id: u32) -> Element {
|
||||||
let kind = use_memo(move || targets.read().get(&id).unwrap().kind);
|
let kind = use_memo(move || targets.read().get(&id).unwrap().kind);
|
||||||
|
|
||||||
tracing::info!("Comonent rendered!");
|
|
||||||
|
|
||||||
rsx! {
|
rsx! {
|
||||||
div {
|
div {
|
||||||
class: "join w-full mt-3",
|
class: "join w-full mt-3",
|
||||||
select {
|
select {
|
||||||
class: "select select-bordered join-item w-1/2",
|
class: "select select-bordered join-item w-1/3",
|
||||||
|
required: true,
|
||||||
oninput: move |event| {
|
oninput: move |event| {
|
||||||
let target_kind = TargetKind::from_string(&event.value());
|
let target_kind = TargetKind::from_string(&event.value());
|
||||||
targets.write().get_mut(&id).unwrap().kind = target_kind;
|
targets.write().get_mut(&id).unwrap().kind = target_kind;
|
||||||
targets.write().get_mut(&id).unwrap().value = String::new();
|
targets.write().get_mut(&id).unwrap().value = String::from("");
|
||||||
},
|
},
|
||||||
option { disabled: true, selected: true, "Selecteer een type" },
|
option { disabled: true, selected: true, value: "", "Selecteer een type" },
|
||||||
option { value: "all", "Iedereen" }
|
option { value: "all", "Iedereen" }
|
||||||
option { value: "group", "Groep" }
|
option { value: "group", "Groep" }
|
||||||
option { value: "day", "Dag" }
|
option { value: "day", "Dag" }
|
||||||
@ -262,16 +237,19 @@ fn TargetValueInput(
|
|||||||
let groups = use_context::<crate::Groups>();
|
let groups = use_context::<crate::Groups>();
|
||||||
let value = use_memo(move || targets.read().get(&id).unwrap().value.clone());
|
let value = use_memo(move || targets.read().get(&id).unwrap().value.clone());
|
||||||
|
|
||||||
|
tracing::info!("Input rendered");
|
||||||
|
|
||||||
rsx! {
|
rsx! {
|
||||||
match target_kind() {
|
match target_kind() {
|
||||||
TargetKind::Group => {
|
TargetKind::Group => {
|
||||||
rsx! {
|
rsx! {
|
||||||
select {
|
select {
|
||||||
class: "select select-bordered join-item w-1/2",
|
class: "select select-bordered join-item w-2/3",
|
||||||
|
required: true,
|
||||||
oninput: move |event| {
|
oninput: move |event| {
|
||||||
targets.write().get_mut(&id).unwrap().value = event.value();
|
targets.write().get_mut(&id).unwrap().value = event.value();
|
||||||
},
|
},
|
||||||
option { disabled: true, selected: true, "Selecteer een groep" }
|
option { disabled: true, selected: true, value: "", "Selecteer een groep" }
|
||||||
for (group_id, group_name) in groups.0 {
|
for (group_id, group_name) in groups.0 {
|
||||||
option { value: group_id, "{group_name}" }
|
option { value: group_id, "{group_name}" }
|
||||||
}
|
}
|
||||||
@ -281,11 +259,12 @@ fn TargetValueInput(
|
|||||||
TargetKind::Day => {
|
TargetKind::Day => {
|
||||||
rsx! {
|
rsx! {
|
||||||
select {
|
select {
|
||||||
class: "select select-bordered join-item w-1/2",
|
class: "select select-bordered join-item w-2/3",
|
||||||
|
required: true,
|
||||||
oninput: move |event| {
|
oninput: move |event| {
|
||||||
targets.write().get_mut(&id).unwrap().value = event.value();
|
targets.write().get_mut(&id).unwrap().value = event.value();
|
||||||
},
|
},
|
||||||
option { disabled: true, selected: true, "Selecteer een dag" }
|
option { disabled: true, selected: true, value: "", "Selecteer een dag" }
|
||||||
option {
|
option {
|
||||||
value: "friday",
|
value: "friday",
|
||||||
"Vrijdag",
|
"Vrijdag",
|
||||||
@ -300,8 +279,9 @@ fn TargetValueInput(
|
|||||||
TargetKind::Hourgroup => {
|
TargetKind::Hourgroup => {
|
||||||
rsx! {
|
rsx! {
|
||||||
select {
|
select {
|
||||||
class: "select select-bordered join-item w-1/4",
|
class: "select select-bordered join-item w-1/3",
|
||||||
option { disabled: true, selected: true, "Selecteer een uur" }
|
required: true,
|
||||||
|
option { disabled: true, selected: true, value: "", "Selecteer een uur" }
|
||||||
option {
|
option {
|
||||||
value: "a",
|
value: "a",
|
||||||
"A",
|
"A",
|
||||||
@ -328,8 +308,9 @@ fn TargetValueInput(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
select {
|
select {
|
||||||
class: "select select-bordered join-item w-1/4",
|
class: "select select-bordered join-item w-1/3",
|
||||||
option { disabled: true, selected: true, "Selecteer een groep" }
|
required: true,
|
||||||
|
option { disabled: true, selected: true, value: "", "Selecteer een groep" }
|
||||||
for i in 1..7 {
|
for i in 1..7 {
|
||||||
option { "{i}" }
|
option { "{i}" }
|
||||||
}
|
}
|
||||||
@ -339,8 +320,9 @@ fn TargetValueInput(
|
|||||||
TargetKind::Hour => {
|
TargetKind::Hour => {
|
||||||
rsx! {
|
rsx! {
|
||||||
select {
|
select {
|
||||||
class: "select select-bordered join-item w-1/2",
|
class: "select select-bordered join-item w-2/3",
|
||||||
option { disabled: true, selected: true, "Selecteer een uur" }
|
required: true,
|
||||||
|
option { disabled: true, selected: true, value: "", "Selecteer een uur" }
|
||||||
option {
|
option {
|
||||||
value: "a",
|
value: "a",
|
||||||
"A",
|
"A",
|
||||||
@ -371,8 +353,8 @@ fn TargetValueInput(
|
|||||||
TargetKind::Member | TargetKind::Account => {
|
TargetKind::Member | TargetKind::Account => {
|
||||||
rsx! {
|
rsx! {
|
||||||
input {
|
input {
|
||||||
class: "input input-bordered join-item w-1/2",
|
class: "input input-bordered join-item w-2/3",
|
||||||
value: "{value}",
|
required: true,
|
||||||
oninput: move |event| {
|
oninput: move |event| {
|
||||||
targets.write().get_mut(&id).unwrap().value = event.value();
|
targets.write().get_mut(&id).unwrap().value = event.value();
|
||||||
},
|
},
|
||||||
@ -380,7 +362,7 @@ fn TargetValueInput(
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
_ => rsx! {
|
_ => rsx! {
|
||||||
div { class: "input input-bordered w-1/2 join-item" }
|
div { class: "input input-bordered w-2/3 join-item" }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
48
src/main.rs
48
src/main.rs
@ -8,7 +8,6 @@ mod util;
|
|||||||
pub use err::Error;
|
pub use err::Error;
|
||||||
|
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
use tracing::Level;
|
|
||||||
|
|
||||||
// Use routes
|
// Use routes
|
||||||
use components::admin::members::migration::Migration;
|
use components::admin::members::migration::Migration;
|
||||||
@ -22,6 +21,7 @@ use components::layout::Global;
|
|||||||
use components::news::create::NewsCreate;
|
use components::news::create::NewsCreate;
|
||||||
use components::news::News;
|
use components::news::News;
|
||||||
use components::settings::Settings;
|
use components::settings::Settings;
|
||||||
|
use tracing::Level;
|
||||||
|
|
||||||
#[derive(Clone, Routable, Debug, PartialEq, serde::Serialize, serde::Deserialize)]
|
#[derive(Clone, Routable, Debug, PartialEq, serde::Serialize, serde::Deserialize)]
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
@ -49,43 +49,29 @@ pub enum Route {
|
|||||||
Migration {},
|
Migration {},
|
||||||
}
|
}
|
||||||
|
|
||||||
const _TAILWIND_URL: &str = manganis::mg!(file("assets/tailwind.css"));
|
#[cfg(feature = "server")]
|
||||||
|
#[tokio::main]
|
||||||
|
async fn main() {
|
||||||
|
dioxus::logger::init(Level::INFO).expect("Failed to init logger");
|
||||||
|
|
||||||
fn main() {
|
|
||||||
// Init logger
|
|
||||||
dioxus_logger::init(Level::INFO).expect("failed to init logger");
|
|
||||||
|
|
||||||
#[cfg(feature = "server")]
|
|
||||||
{
|
|
||||||
use axum::routing::*;
|
|
||||||
|
|
||||||
// Spawn main tokio runtime
|
|
||||||
tokio::runtime::Runtime::new()
|
|
||||||
.unwrap()
|
|
||||||
.block_on(async move {
|
|
||||||
// Initialize surrealdb connection
|
// Initialize surrealdb connection
|
||||||
util::surrealdb::initialize()
|
util::surrealdb::initialize()
|
||||||
.await
|
.await
|
||||||
.expect("Error while initializing surrealdb");
|
.expect("Error while initializing surrealdb");
|
||||||
|
|
||||||
// Create axum app
|
let address = dioxus_cli_config::fullstack_address_or_localhost();
|
||||||
let app = Router::new()
|
|
||||||
.serve_dioxus_application(ServeConfig::builder().build(), || {
|
|
||||||
VirtualDom::new(App)
|
|
||||||
})
|
|
||||||
.await;
|
|
||||||
|
|
||||||
// Run axum app
|
let router = axum::Router::new().serve_dioxus_application(ServeConfigBuilder::default(), App);
|
||||||
let addr = std::net::SocketAddr::from(([127, 0, 0, 1], 8080));
|
|
||||||
let listener = tokio::net::TcpListener::bind(&addr).await.unwrap();
|
|
||||||
|
|
||||||
axum::serve(listener, app.into_make_service())
|
let router = router.into_make_service();
|
||||||
.await
|
let listener = tokio::net::TcpListener::bind(address).await.unwrap();
|
||||||
.unwrap();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
launch(App);
|
axum::serve(listener, router).await.unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(feature = "server"))]
|
||||||
|
fn main() {
|
||||||
|
dioxus::launch(App);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
@ -117,6 +103,10 @@ fn App() -> Element {
|
|||||||
use_context_provider(|| hours);
|
use_context_provider(|| hours);
|
||||||
|
|
||||||
rsx! {
|
rsx! {
|
||||||
|
document::Stylesheet {
|
||||||
|
href: asset!("assets/tailwind.css")
|
||||||
|
}
|
||||||
|
|
||||||
div {
|
div {
|
||||||
class: "h-screen flex flex-col",
|
class: "h-screen flex flex-col",
|
||||||
Router::<Route> {}
|
Router::<Route> {}
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
pub mod member;
|
pub mod member;
|
||||||
|
pub mod news;
|
||||||
pub mod session;
|
pub mod session;
|
||||||
pub mod user;
|
pub mod user;
|
||||||
|
68
src/util/model/news.rs
Normal file
68
src/util/model/news.rs
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
#[cfg(feature = "server")]
|
||||||
|
use crate::util::surrealdb::{thing_to_string, DB};
|
||||||
|
#[cfg(feature = "server")]
|
||||||
|
use surrealdb::sql::{
|
||||||
|
statements::{BeginStatement, CommitStatement},
|
||||||
|
Thing,
|
||||||
|
};
|
||||||
|
|
||||||
|
#[derive(PartialEq, Clone, Copy, Debug, Deserialize, Serialize, Eq)]
|
||||||
|
pub enum TargetKind {
|
||||||
|
None,
|
||||||
|
All,
|
||||||
|
Group,
|
||||||
|
Hourgroup,
|
||||||
|
Hour,
|
||||||
|
Member,
|
||||||
|
Account,
|
||||||
|
Day,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TargetKind {
|
||||||
|
pub fn from_string(input: &str) -> Self {
|
||||||
|
match input {
|
||||||
|
"all" => Self::All,
|
||||||
|
"group" => Self::Group,
|
||||||
|
"hourgroup" => Self::Hourgroup,
|
||||||
|
"hour" => Self::Hour,
|
||||||
|
"member" => Self::Member,
|
||||||
|
"account" => Self::Account,
|
||||||
|
"day" => Self::Day,
|
||||||
|
_ => Self::None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(PartialEq, Debug, Deserialize, Serialize, Clone, Eq)]
|
||||||
|
pub struct Target {
|
||||||
|
pub kind: TargetKind,
|
||||||
|
pub value: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize, Serialize, PartialEq, Eq, Clone)]
|
||||||
|
pub struct News {
|
||||||
|
#[cfg_attr(feature = "server", serde(deserialize_with = "thing_to_string"))]
|
||||||
|
pub id: String,
|
||||||
|
pub title: String,
|
||||||
|
pub body: String,
|
||||||
|
pub tagets: Vec<Target>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "server")]
|
||||||
|
impl News {
|
||||||
|
// pub async fn new(
|
||||||
|
// title: String,
|
||||||
|
// body: String,
|
||||||
|
// targets: Vec<Target>,
|
||||||
|
// ) -> Result<Self, crate::Error> {
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "server")]
|
||||||
|
fn fetch_targets(targets: Vec<Target>) {
|
||||||
|
let mut transaction = DB.query(BeginStatement::default());
|
||||||
|
|
||||||
|
for target in targets {}
|
||||||
|
}
|
@ -3,8 +3,6 @@ use crate::util::surrealdb::{thing_to_string, DB};
|
|||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
#[cfg(feature = "server")]
|
|
||||||
use surrealdb::sql::Thing;
|
|
||||||
|
|
||||||
use super::user::User;
|
use super::user::User;
|
||||||
|
|
||||||
@ -51,11 +49,7 @@ impl Session {
|
|||||||
|
|
||||||
cookie.set_same_site(SameSite::Strict);
|
cookie.set_same_site(SameSite::Strict);
|
||||||
|
|
||||||
server_context()
|
server_context().response_parts_mut().headers.insert(
|
||||||
.response_parts_mut()
|
|
||||||
.unwrap()
|
|
||||||
.headers
|
|
||||||
.insert(
|
|
||||||
header::SET_COOKIE,
|
header::SET_COOKIE,
|
||||||
HeaderValue::from_str(&cookie.to_string())?,
|
HeaderValue::from_str(&cookie.to_string())?,
|
||||||
);
|
);
|
||||||
@ -104,11 +98,7 @@ impl Session {
|
|||||||
|
|
||||||
cookie.set_same_site(SameSite::Strict);
|
cookie.set_same_site(SameSite::Strict);
|
||||||
|
|
||||||
server_context()
|
server_context().response_parts_mut().headers.insert(
|
||||||
.response_parts_mut()
|
|
||||||
.unwrap()
|
|
||||||
.headers
|
|
||||||
.insert(
|
|
||||||
header::SET_COOKIE,
|
header::SET_COOKIE,
|
||||||
HeaderValue::from_str(&cookie.to_string())?,
|
HeaderValue::from_str(&cookie.to_string())?,
|
||||||
);
|
);
|
||||||
|
@ -16,7 +16,11 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub async fn initialize() -> surrealdb::Result<()> {
|
pub async fn initialize() -> surrealdb::Result<()> {
|
||||||
DB.connect::<Ws>("localhost:8000").await?;
|
tracing::info!("Connectiong to surrealdb");
|
||||||
|
|
||||||
|
DB.connect::<Ws>("localhost:8000")
|
||||||
|
.await
|
||||||
|
.expect("Failed to connect to surrealdb");
|
||||||
|
|
||||||
DB.signin(Root {
|
DB.signin(Root {
|
||||||
username: "root",
|
username: "root",
|
||||||
@ -26,7 +30,7 @@ pub async fn initialize() -> surrealdb::Result<()> {
|
|||||||
|
|
||||||
DB.use_ns("wrbapp").use_db("wrbapp").await?;
|
DB.use_ns("wrbapp").use_db("wrbapp").await?;
|
||||||
|
|
||||||
apply_queries().await?;
|
apply_queries().await.expect("Failed to apply queries");
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -47,7 +51,8 @@ async fn apply_queries() -> surrealdb::Result<()> {
|
|||||||
DEFINE INDEX userEmailIndex ON TABLE user COLUMNS email UNIQUE;
|
DEFINE INDEX userEmailIndex ON TABLE user COLUMNS email UNIQUE;
|
||||||
",
|
",
|
||||||
)
|
)
|
||||||
.await?;
|
.await
|
||||||
|
.expect("Failed to apply user query");
|
||||||
|
|
||||||
DB.query(
|
DB.query(
|
||||||
"
|
"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user