crm.rs 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. //! Tiny CRM: A port of the Yew CRM example to Dioxus.
  2. use dioxus::prelude::*;
  3. use dioxus_router::prelude::*;
  4. fn main() {
  5. dioxus_desktop::launch(App);
  6. }
  7. #[derive(Routable, Clone)]
  8. #[rustfmt::skip]
  9. enum Route {
  10. #[route("/")]
  11. ClientList {},
  12. #[route("/new")]
  13. ClientAdd {},
  14. #[route("/settings")]
  15. Settings {},
  16. }
  17. #[derive(Clone, Debug, Default)]
  18. pub struct Client {
  19. pub first_name: String,
  20. pub last_name: String,
  21. pub description: String,
  22. }
  23. type ClientContext = Vec<Client>;
  24. #[component]
  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. #[component]
  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. #[component]
  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. cx.render(rsx! {
  75. h2 { "Add new Client" }
  76. form {
  77. class: "pure-form pure-form-aligned",
  78. onsubmit: move |_| {
  79. let mut clients = clients.write();
  80. clients.push(Client {
  81. first_name: first_name.to_string(),
  82. last_name: last_name.to_string(),
  83. description: description.to_string(),
  84. });
  85. dioxus_router::router().push(Route::ClientList {});
  86. },
  87. fieldset {
  88. div {
  89. class: "pure-control-group",
  90. label {
  91. "for": "first_name",
  92. "First Name"
  93. }
  94. input {
  95. id: "first_name",
  96. "type": "text",
  97. placeholder: "First Name…",
  98. required: "",
  99. value: "{first_name}",
  100. oninput: move |e| first_name.set(e.value.clone())
  101. }
  102. }
  103. div {
  104. class: "pure-control-group",
  105. label {
  106. "for": "last_name",
  107. "Last Name"
  108. }
  109. input {
  110. id: "last_name",
  111. "type": "text",
  112. placeholder: "Last Name…",
  113. required: "",
  114. value: "{last_name}",
  115. oninput: move |e| last_name.set(e.value.clone())
  116. }
  117. }
  118. div {
  119. class: "pure-control-group",
  120. label {
  121. "for": "description",
  122. "Description"
  123. }
  124. textarea {
  125. id: "description",
  126. placeholder: "Description…",
  127. value: "{description}",
  128. oninput: move |e| description.set(e.value.clone())
  129. }
  130. }
  131. div {
  132. class: "pure-controls",
  133. button {
  134. "type": "submit",
  135. class: "pure-button pure-button-primary",
  136. "Save"
  137. }
  138. Link {
  139. to: Route::ClientList {},
  140. class: "pure-button pure-button-primary red",
  141. "Cancel"
  142. }
  143. }
  144. }
  145. }
  146. })
  147. }
  148. #[component]
  149. fn Settings(cx: Scope) -> Element {
  150. let clients = use_shared_state::<ClientContext>(cx).unwrap();
  151. cx.render(rsx! {
  152. h2 { "Settings" }
  153. button {
  154. class: "pure-button pure-button-primary red",
  155. onclick: move |_| {
  156. let mut clients = clients.write();
  157. clients.clear();
  158. },
  159. "Remove all Clients"
  160. }
  161. Link {
  162. to: Route::ClientList {},
  163. class: "pure-button",
  164. "Go back"
  165. }
  166. })
  167. }