crm.rs 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. //! Tiny CRM: A port of the Yew CRM example to Dioxus.
  2. #![allow(non_snake_case)]
  3. use dioxus::prelude::*;
  4. use dioxus_router::prelude::*;
  5. fn main() {
  6. dioxus_desktop::launch(App);
  7. }
  8. #[derive(Routable, Clone)]
  9. #[rustfmt::skip]
  10. enum Route {
  11. #[route("/")]
  12. ClientList {},
  13. #[route("/new")]
  14. ClientAdd {},
  15. #[route("/settings")]
  16. Settings {},
  17. }
  18. #[derive(Clone, Debug, Default)]
  19. pub struct Client {
  20. pub first_name: String,
  21. pub last_name: String,
  22. pub description: String,
  23. }
  24. type ClientContext = Vec<Client>;
  25. fn App(cx: Scope) -> Element {
  26. use_shared_state_provider::<ClientContext>(cx, Default::default);
  27. render! {
  28. link {
  29. rel: "stylesheet",
  30. href: "https://unpkg.com/purecss@2.0.6/build/pure-min.css",
  31. integrity: "sha384-Uu6IeWbM+gzNVXJcM9XV3SohHtmWE+3VGi496jvgX1jyvDTXfdK+rfZc8C1Aehk5",
  32. crossorigin: "anonymous",
  33. }
  34. style { "
  35. .red {{
  36. background-color: rgb(202, 60, 60) !important;
  37. }}
  38. " }
  39. h1 { "Dioxus CRM Example" }
  40. Router::<Route> {}
  41. }
  42. }
  43. #[inline_props]
  44. fn ClientList(cx: Scope) -> Element {
  45. let clients = use_shared_state::<ClientContext>(cx).unwrap();
  46. cx.render(rsx! {
  47. h2 { "List of Clients" }
  48. Link {
  49. to: Route::ClientAdd {},
  50. class: "pure-button pure-button-primary",
  51. "Add Client"
  52. }
  53. Link {
  54. to: Route::Settings {},
  55. class: "pure-button",
  56. "Settings"
  57. }
  58. clients.read().iter().map(|client| rsx! {
  59. div {
  60. class: "client",
  61. style: "margin-bottom: 50px",
  62. p { "Name: {client.first_name} {client.last_name}" }
  63. p { "Description: {client.description}" }
  64. }
  65. })
  66. })
  67. }
  68. #[inline_props]
  69. fn ClientAdd(cx: Scope) -> Element {
  70. let clients = use_shared_state::<ClientContext>(cx).unwrap();
  71. let first_name = use_state(cx, String::new);
  72. let last_name = use_state(cx, String::new);
  73. let description = use_state(cx, String::new);
  74. let navigator = use_navigator(cx);
  75. cx.render(rsx! {
  76. h2 { "Add new Client" }
  77. form {
  78. class: "pure-form pure-form-aligned",
  79. onsubmit: move |_| {
  80. let mut clients = clients.write();
  81. clients.push(Client {
  82. first_name: first_name.to_string(),
  83. last_name: last_name.to_string(),
  84. description: description.to_string(),
  85. });
  86. navigator.push(Route::ClientList {});
  87. },
  88. fieldset {
  89. div {
  90. class: "pure-control-group",
  91. label {
  92. "for": "first_name",
  93. "First Name"
  94. }
  95. input {
  96. id: "first_name",
  97. "type": "text",
  98. placeholder: "First Name…",
  99. required: "",
  100. value: "{first_name}",
  101. oninput: move |e| first_name.set(e.value.clone())
  102. }
  103. }
  104. div {
  105. class: "pure-control-group",
  106. label {
  107. "for": "last_name",
  108. "Last Name"
  109. }
  110. input {
  111. id: "last_name",
  112. "type": "text",
  113. placeholder: "Last Name…",
  114. required: "",
  115. value: "{last_name}",
  116. oninput: move |e| last_name.set(e.value.clone())
  117. }
  118. }
  119. div {
  120. class: "pure-control-group",
  121. label {
  122. "for": "description",
  123. "Description"
  124. }
  125. textarea {
  126. id: "description",
  127. placeholder: "Description…",
  128. value: "{description}",
  129. oninput: move |e| description.set(e.value.clone())
  130. }
  131. }
  132. div {
  133. class: "pure-controls",
  134. button {
  135. "type": "submit",
  136. class: "pure-button pure-button-primary",
  137. "Save"
  138. }
  139. Link {
  140. to: Route::ClientList {},
  141. class: "pure-button pure-button-primary red",
  142. "Cancel"
  143. }
  144. }
  145. }
  146. }
  147. })
  148. }
  149. #[inline_props]
  150. fn Settings(cx: Scope) -> Element {
  151. let clients = use_shared_state::<ClientContext>(cx).unwrap();
  152. cx.render(rsx! {
  153. h2 { "Settings" }
  154. button {
  155. class: "pure-button pure-button-primary red",
  156. onclick: move |_| {
  157. let mut clients = clients.write();
  158. clients.clear();
  159. },
  160. "Remove all Clients"
  161. }
  162. Link {
  163. to: Route::ClientList {},
  164. class: "pure-button",
  165. "Go back"
  166. }
  167. })
  168. }