umuro

001-client

Jul 3rd, 2025
20
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Rust 137.09 KB | None | 0 0
  1. This file is a merged representation of a subset of the codebase, containing specifically included files, combined into a single document by Repomix.
  2.  
  3. ================================================================
  4. File Summary
  5. ================================================================
  6.  
  7. Purpose:
  8. --------
  9. This file contains a packed representation of a subset of the repository's contents that is considered the most important context.
  10. It is designed to be easily consumable by AI systems for analysis, code review,
  11. or other automated processes.
  12.  
  13. File Format:
  14. ------------
  15. The content is organized as follows:
  16. 1. This summary section
  17. 2. Repository information
  18. 3. Directory structure
  19. 4. Repository files (if enabled)
  20. 5. Multiple file entries, each consisting of:
  21.  a. A separator line (================)
  22.  b. The file path (File: path/to/file)
  23.  c. Another separator line
  24.  d. The full contents of the file
  25.  e. A blank line
  26.  
  27. Usage Guidelines:
  28. -----------------
  29. - This file should be treated as read-only. Any changes should be made to the
  30.  original repository files, not this packed version.
  31. - When processing this file, use the file path to distinguish
  32.  between different files in the repository.
  33. - Be aware that this file may contain sensitive information. Handle it with
  34.  the same level of security as you would the original repository.
  35.  
  36. Notes:
  37. ------
  38. - Some files may have been excluded based on .gitignore rules and Repomix's configuration
  39. - Binary files are not included in this packed representation. Please refer to the Repository Structure section for a complete list of file paths, including binary files
  40. - Only files matching these patterns are included: gmm_client/src/pages/year_to_date.rs, gmm_client/src/pages/well_rev.rs, gmm_client/src/pages/tax_year.rs, gmm_client/src/pages/stats.rs, gmm_client/src/pages/leases.rs, gmm_client/src/pages/jibs.rs, gmm_client/src/pages/incoming.rs, gmm_client/src/pages/dashboard.rs, gmm_client/src/pages/contacts.rs, gmm_client/src/pages/assets.rs, gmm_client/src/components/table.rs, gmm_client/src/components/pie_chart.rs, gmm_client/src/server/app_pools.rs
  41. - Files matching patterns in .gitignore are excluded
  42. - Files matching default ignore patterns are excluded
  43. - Files are sorted by Git change count (files with more changes are at the bottom)
  44.  
  45.  
  46. ================================================================
  47. Directory Structure
  48. ================================================================
  49. gmm_client/
  50.   src/
  51.     components/
  52.       pie_chart.rs
  53.       table.rs
  54.     pages/
  55.       assets.rs
  56.       contacts.rs
  57.       dashboard.rs
  58.       incoming.rs
  59.       jibs.rs
  60.       leases.rs
  61.       stats.rs
  62.       tax_year.rs
  63.       well_rev.rs
  64.       year_to_date.rs
  65.     server/
  66.       app_pools.rs
  67.  
  68. ================================================================
  69. Files
  70. ================================================================
  71.  
  72. ================
  73. File: gmm_client/src/components/pie_chart.rs
  74. ================
  75. use leptos::*;
  76.  
  77. /// Represents a single slice of the pie chart.
  78. #[derive(Debug, Clone)]
  79. pub struct PieSlice {
  80.     pub label: String,
  81.     pub value: f64,
  82.     pub color: String,
  83. }
  84.  
  85. #[component]
  86. pub fn PieChart(
  87.     title: String,
  88.     sub_title: String,
  89.     mut data: Vec<PieSlice>,
  90. ) -> impl IntoView {
  91.     data.sort_by(|a, b| a.label.cmp(&b.label));
  92.    
  93.     let angles = {
  94.         let total: f64 = data.iter().map(|s| s.value).sum();
  95.         let mut start_angle = -90.0;
  96.         let mut computed_angles = Vec::new();
  97.  
  98.         for slice in &data {
  99.             let angle = (slice.value / total) * 360.0;
  100.             computed_angles.push((start_angle, start_angle + angle));
  101.             start_angle += angle;
  102.         }
  103.  
  104.         computed_angles
  105.     };
  106.  
  107.     view! {
  108.         <div class="pie-chart-wrapper">
  109.             <h3 class="pie-header">{title.clone()}</h3>
  110.             <p class="pie-sub">{sub_title}</p>
  111.  
  112.             <div class="pie-chart-container">
  113.                 <svg width="250" height="255" viewBox="0 0 250 255" class="pie-chart">
  114.                     {
  115.                         if data.len() == 1 {
  116.                             let slice = &data[0];
  117.                             vec![
  118.                                 view! {
  119.                                         <path
  120.             d="M125,2.5 A125,125 0 1,1 124.9,2.5 Z"
  121.             fill={slice.color.clone()}
  122.             stroke="white"
  123.             stroke-width="1"
  124.         />
  125.                                 }
  126.                             ]
  127.                         } else {
  128.                             data.iter().zip(angles.iter()).enumerate().map(|(_i, (slice, &(start, end)))| {
  129.                                 let radius = 125.0;
  130.                                 let center_x = 125.0;
  131.                                 let center_y = 127.5;
  132.  
  133.                                 let start_x = center_x + radius * start.to_radians().cos();
  134.                                 let start_y = center_y + radius * start.to_radians().sin();
  135.                                 let end_x = center_x + radius * end.to_radians().cos();
  136.                                 let end_y = center_y + radius * end.to_radians().sin();
  137.  
  138.                                 let large_arc = if end - start > 180.0 { 1 } else { 0 };
  139.                                 let path = format!(
  140.                                     "M{},{} L{},{} A{},{} 0 {} 1 {},{} Z",
  141.                                     center_x, center_y,
  142.                                     start_x, start_y,
  143.                                     radius, radius,
  144.                                     large_arc,
  145.                                     end_x, end_y
  146.                                 );
  147.  
  148.                                 view! {
  149.                                     <path d=path fill={slice.color.clone()} stroke="white" stroke-width="1"/>
  150.                                 }
  151.                             }).collect::<Vec<_>>()
  152.                         }
  153.                     }
  154.                 </svg>
  155.  
  156.                 <table class="pie-chart-legend">
  157.                     <tbody>
  158.                         {data.iter().map(|slice| {
  159.                             view! {
  160.                                 <tr>
  161.                                     <td>
  162.                                         <svg width="20" height="20" xmlns="http://www.w3.org/2000/svg">
  163.                                             <path d="M0 20 L6.8404 1.20615 A20 20 0 0 1 20 20Z" fill={slice.color.clone()} stroke="white" stroke-width="1"/>
  164.                                         </svg>
  165.                                     </td>
  166.                                     <td>{
  167.                                         slice.label.clone()
  168.                                         // slice.label.clone().replace('.', " ") without the dot
  169.                                     }</td>
  170.                                     <td>{format!("{:.2}%", slice.value)}</td>
  171.                                 </tr>
  172.                             }
  173.                         }).collect::<Vec<_>>()}
  174.                     </tbody>
  175.                 </table>
  176.             </div>
  177.         </div>
  178.     }
  179. }
  180.  
  181. ================
  182. File: gmm_client/src/components/table.rs
  183. ================
  184. use leptos::*;
  185.  
  186. use crate::components::popover::Popover;
  187.  
  188. #[derive(Clone, Debug)]
  189. pub struct TableData {
  190.     pub headers: Vec<View>,
  191.     pub rows: Vec<Vec<View>>,
  192.     pub links: Vec<Option<Vec<String>>>,
  193.     pub has_totals: bool,
  194. }
  195.  
  196. #[component]
  197. pub fn Table(
  198.     #[prop(optional, default = TableData {
  199.         headers: vec![],
  200.         rows: vec![],
  201.         links: vec![],
  202.         has_totals: false,
  203.     })]
  204.     data: TableData,
  205. ) -> impl IntoView {
  206.     let (active_popover, set_active_popover) = create_signal(None::<usize>);
  207.  
  208.     view! {
  209.         <div class="w-auto table-wrapper">
  210.             <table class="table-content mb-3">
  211.                 <thead>
  212.                     <tr class="bg-table-header">
  213.                         {data.headers.iter().map(|header| {
  214.                             view! {
  215.                                 <th class="bg-table-header">
  216.                                     <div class="d-flex align-items-center justify-content-center min-w-100 bg-table-header">
  217.                                         {header}
  218.                                         <div class="margin-sort">
  219.                                             <div>
  220.                                                 <svg viewBox="0 0 100 100">
  221.                                                     <path d="m 0,100 50,-100 50,100 z"></path>
  222.                                                 </svg>
  223.                                             </div>
  224.                                             <div>
  225.                                                 <svg viewBox="0 0 100 100">
  226.                                                     <path d="m 0,0 50,100 50,-100 z"></path>
  227.                                                 </svg>
  228.                                             </div>
  229.                                         </div>
  230.                                     </div>
  231.                                 </th>
  232.                             }
  233.                         }).collect::<Vec<_>>()}
  234.                     </tr>
  235.                 </thead>
  236.                 <tbody>
  237.                     {data.rows.iter().enumerate().map(|(index, row)| {
  238.                         let is_last_row = data.has_totals && index == data.rows.len() - 1;
  239.                         let row_class = if is_last_row {
  240.                             "border-t-2"
  241.                         } else {
  242.                             ""
  243.                         };
  244.                         let row_link = data.links.get(index).cloned().flatten().unwrap_or_default();
  245.  
  246.                         view! {
  247.                             <tr class={row_class}>
  248.                                 {
  249.                                     if !row_link.is_empty() {
  250.                                         row.iter().enumerate().map(|(cell_index, cell)| {
  251.                                             let cell_class = if cell_index == 0 {
  252.                                                 "text-left"
  253.                                             } else {
  254.                                                 "text-right"
  255.                                             };
  256.  
  257.                                             if row_link.len() == 1 {
  258.                                                 view! {
  259.                                                     <td class="text-right">
  260.                                                         <a href={row_link[0].clone()} target="_blank" class="black">
  261.                                                             {cell}
  262.                                                         </a>
  263.                                                     </td>
  264.                                                 }
  265.                                             } else {
  266.                                                 let popover_index = index * 1000 + cell_index;
  267.  
  268.                                                 view! {
  269.                                                     <td class={cell_class}>
  270.                                                         <Popover
  271.                                                             index={popover_index}
  272.                                                             links={row_link.clone()}
  273.                                                             trigger={cell.clone()}
  274.                                                             active_popover={active_popover.clone()}
  275.                                                             set_active_popover={set_active_popover.clone()}
  276.                                                             text_align={cell_class.to_string()}
  277.                                                         />
  278.                                                     </td>
  279.                                                 }
  280.                                             }
  281.                                         }).collect::<Vec<_>>()
  282.                                     } else {
  283.                                         row.iter().enumerate().map(|(cell_index, cell)| {
  284.                                             let cell_class = if cell_index == 0 {
  285.                                                 "text-left"
  286.                                             } else {
  287.                                                 "text-right"
  288.                                             };
  289.                                             view! { <td class={cell_class}>{cell}</td> }
  290.                                         }).collect::<Vec<_>>()
  291.                                     }
  292.                                 }
  293.                             </tr>
  294.                         }
  295.                     }).collect::<Vec<_>>() }
  296.                 </tbody>
  297.             </table>
  298.         </div>
  299.     }
  300. }
  301.  
  302. ================
  303. File: gmm_client/src/pages/assets.rs
  304. ================
  305. use leptos::*; // Import the Leptos framework // Import the AssetsResource struct
  306. use std::vec;
  307. use crate::components::table::*; // Import the Table component
  308. use crate::tables::assets::resource::AssetsResource;
  309. use crate::components::table_skeleton::TableSkeleton; // Import the TableSkeleton component
  310.  
  311. #[component]
  312. pub fn Assets() -> impl IntoView {
  313.     // Create an instance of the AssetsResource to fetch asset data
  314.     let assets_resource = AssetsResource::new();
  315.  
  316.     view! {
  317.         <div class="tables">
  318.             <h2 class="title-guardian-content">Assets</h2>
  319.             <p class="font-georgia mb-0">A current listing of your owned assets.</p>
  320.  
  321.             // Create a transition with a fallback view when data is still loading
  322.             <Suspense fallback={move || view!
  323.                 {
  324.                     <div>
  325.                         <TableSkeleton />
  326.                     </div>
  327.                 }
  328.             }>
  329.                 {move ||
  330.                     // Check the result of fetching asset data
  331.                     match assets_resource.revenue_rows.get() {
  332.                         // If assets data is successfully fetched
  333.                         Some(Ok(assets)) => {
  334.                             let visibility_classes: Vec<(RwSignal<String>, RwSignal<bool>)> =
  335.                             assets.iter().map(|_| (create_rw_signal("max-width-text-hidden".to_string()), create_rw_signal(false))).collect();
  336.  
  337.                             // Define the table data structure
  338.                             let data_assets = TableData {
  339.                                 // Table headers
  340.                                 headers: vec![
  341.                                     view! { <p>"State"</p> }.into_view(),
  342.                                     view! { <p>"Location Details"</p> }.into_view(),
  343.                                     view! { <p>"Interest Type"</p> }.into_view(),
  344.                                     view! { <p>"Area Share"<br />"(NMA)"</p> }.into_view(),
  345.                                     view! { <p>"Conveyance Type"</p> }.into_view(),
  346.                                 ],
  347.                                 // Table rows mapped from the fetched assets
  348.                                 rows: assets.iter().enumerate().map(|(index, asset)| {
  349.                                     let visibility_class = visibility_classes[index].clone();
  350.  
  351.                                     let toggle_visibility = move |_| {
  352.                                         let current_class = visibility_class.0.get_untracked();
  353.                                         if current_class == "max-width-text-hidden" {
  354.                                             visibility_class.0.set("max-width-text-visible".to_string());
  355.                                         } else {
  356.                                             visibility_class.0.set("max-width-text-hidden".to_string());
  357.                                         }
  358.                                     };
  359.  
  360.                                     let full_text = format!(
  361.                                         "{} {}",
  362.                                         asset.county.as_deref().unwrap_or("").trim(),
  363.                                         asset.full_legal_description.as_deref().unwrap_or("").trim()
  364.                                     ).trim().to_string();
  365.  
  366.                                     let show_button = full_text.chars().count() > 40;
  367.  
  368.                                     vec![
  369.                                         view! { <p>{asset.state.clone()}</p> }.into_view(),
  370.                                         view! {
  371.                                             <div class="d-flex justify-content-between align-items-end max-width-text">
  372.                                                 <p class=move || format!("text-left {}", visibility_class.0.get())>
  373.                                                     {format!(
  374.                                                         "{} {}",
  375.                                                         asset.county.clone().unwrap_or_default(),
  376.                                                         asset.full_legal_description.clone().unwrap_or_default()
  377.                                                     )}
  378.                                                 </p>
  379.  
  380.                                                 {
  381.                                                     if show_button {
  382.                                                         view! {
  383.                                                             <button
  384.                                                                 class="toggle-button-visibility-class text-right"
  385.                                                                 on:click=toggle_visibility
  386.                                                             >
  387.                                                                 {move || if visibility_class.0.get() == "max-width-text-hidden" {
  388.                                                                     view!{ <p>"... more"</p> }
  389.                                                                 } else {
  390.                                                                     view!{ <p>"... less"</p> }
  391.                                                                 }}
  392.                                                             </button>
  393.                                                         }.into_view()
  394.                                                     } else {
  395.                                                         view! {}.into_view()
  396.                                                     }
  397.                                                 }
  398.                                             </div>
  399.                                         }.into_view(),
  400.                                         view! { <p class="text-left">{asset.interest_type.clone()}</p> }.into_view(),
  401.                                         view! { <p class="text-right">{asset.area_share_nma.clone()}</p> }.into_view(),
  402.                                         view! { <p class="text-right">{asset.conveyance_type.clone()}</p> }.into_view(),
  403.                                     ]
  404.                                 }).collect::<Vec<_>>(),
  405.                                 // Links for each row (example with Google links)
  406.                                 links: vec![Some(vec!["https://www.google.com".to_string(); 4])],
  407.                                 // No totals to display in the table
  408.                                 has_totals: false,
  409.                             };
  410.                             // Render the table with the provided data
  411.                             view! {
  412.                                 <div>
  413.                                     <Table data={data_assets} />
  414.                                 </div>
  415.                             }
  416.                         },
  417.                         // If an error occurs while fetching data
  418.                         Some(Err(_)) => {
  419.                             log::error!("Error fetching assets {}", assets_resource.revenue_rows.get().unwrap().err().unwrap());
  420.                             view! { <div><p>"Error..."</p></div> }
  421.                         },
  422.                         // If no data is available (still loading)
  423.                         None => view! {
  424.                             <div>
  425.                                 <TableSkeleton />
  426.                             </div>
  427.                         },
  428.                     }
  429.                 }
  430.             </Suspense>
  431.         </div>
  432.     }
  433. }
  434.  
  435. ================
  436. File: gmm_client/src/pages/contacts.rs
  437. ================
  438. use leptos::*;
  439. use crate::hooks::use_is_pw_layout;
  440.  
  441. #[component]
  442. pub fn Contacts() -> impl IntoView {
  443.   let is_pw_layout = use_is_pw_layout::use_is_pw_layout();
  444.  
  445.     view! {
  446.       <>
  447.       {
  448.         (move || if is_pw_layout.get() {
  449.           view! {
  450.             <h2 class="title-guardian-content">Contacts Us</h2>
  451.           }
  452.         } else {
  453.           view! {
  454.             <h2 class="title-guardian-content">Contacts</h2>
  455.           }
  456.         })()
  457.       }
  458.         <p class="font-georgia">Should you have any questions or need anything further, please feel free to contact us. Thank you for the opportunity to provide our services. To save your visualization, please click download and save the file as you wish. You can also view this visualization from your computer, ipad or tablet or smart tv. </p>
  459.  
  460.         {move || if is_pw_layout.get() {
  461.           view! {
  462.             <>
  463.               <h2 class="title-guardian-content">Post Office Box</h2>
  464.               <p class="font-georgia mb-0">PW Energy</p>
  465.               <p class="font-georgia mb-0">PO Box 471939</p>
  466.               <p class="font-georgia mb-0">Fort Worth, Texas 76147</p>
  467.  
  468.               <h2 class="title-guardian-content">Lead Contacts</h2>
  469.               <table class="table-contacts w-auto d-flex">
  470.                 <tr>
  471.                   <td class="font-georgia">
  472.                     <div class="d-flex flex-column">
  473.                       <span>Bryan Frazier, CPL</span>
  474.                       <span>Partner, Head of Energy Asset Management</span>
  475.                       <span>Email: <a href="mailto:[email protected]">BryanF@PrivateWealth.com</a></span>
  476.                       <span>Phone: 817-247-7858</span>
  477.                     </div>
  478.                   </td>
  479.                 </tr>
  480.                 <tr>
  481.                   <td class="font-georgia">
  482.                     <div class="d-flex flex-column">
  483.                       <span>Pedie Monta, CPL</span>
  484.                       <span>Director of Land - Energy Asset Management</span>
  485.                       <span>Email: <a href="mailto:[email protected]">PedieM@PrivateWealth.com</a></span>
  486.                       <span>Phone: 907-723-9340</span>
  487.                     </div>
  488.                   </td>
  489.                 </tr>
  490.                 <tr>
  491.                   <td class="font-georgia">
  492.                     <div class="d-flex flex-column">
  493.                       <span>Mac Laas, CPL</span>
  494.                       <span>Senior Landman - Energy Asset Management</span>
  495.                       <span>Email: <a href="mailto:[email protected]">MacL@PrivateWealth.com</a></span>
  496.                       <span>Phone: 210-296-7099</span>
  497.                     </div>
  498.                   </td>
  499.                 </tr>
  500.               </table>
  501.             </>
  502.           }
  503.         } else {
  504.           view! {
  505.             <>
  506.               <h2 class="title-guardian-footer">Main Office</h2>
  507.               <p class="font-georgia">(888) 348-7318</p>
  508.               <p class="font-georgia">Guardian Mineral Management & Consulting</p>
  509.               <p class="font-georgia">6115 Camp Bowie Blvd, Suite 245</p>
  510.               <p class="font-georgia">Fort Worth, Texas 76116</p>
  511.  
  512.               <h2 class="title-guardian-footer">Post Office Box</h2>
  513.               <p class="font-georgia">Guardian Mineral Management & Consulting</p>
  514.               <p class="font-georgia">PO Box 471489</p>
  515.               <p class="font-georgia">Fort Worth, Texas 76147</p>
  516.  
  517.               <h2 class="title-guardian-footer">Lead Contacts</h2>
  518.               <table class="table-contacts w-auto">
  519.                 <tr>
  520.                   <td class="font-georgia">
  521.                     <div class="d-flex flex-column">
  522.                       <span>Diana Frazier, CPL</span>
  523.                       <span>Founder and President</span>
  524.                       <span>Email: <a href="mailto:[email protected]">Diana@GuardianMM.com</a></span>
  525.                       <span>Cell: (817) 808-1430</span>
  526.                     </div>
  527.                   </td>
  528.                   <td class="font-georgia">
  529.                     <div class="d-flex flex-column">
  530.                       <span>June D Silva</span>
  531.                       <span>Director of Analysis and Information Visualization</span>
  532.                       <span>Email: <a href="[email protected]">June@GuardianMM.com</a></span>
  533.                       <span>Cell: 312-804-0087</span>
  534.                     </div>
  535.                   </td>
  536.                 </tr>
  537.                 <tr>
  538.                   <td class="font-georgia">
  539.                     <div class="d-flex flex-column">
  540.                       <span>Marcia Newton</span>
  541.                       <span>Office Manager</span>
  542.                       <span>Email: <a href="[email protected]">Marcia@GuardianMM.com</a></span>
  543.                       <span>Cell: 682-269-8765</span>
  544.                     </div>
  545.                   </td>
  546.                   <td class="font-georgia">
  547.                     <div class="d-flex flex-column">
  548.                       <span>Grant Carlisle, CPL</span>
  549.                       <span>VP of Land</span>
  550.                       <span>Email: <a href="[email protected]">Grant@GuardianMM.com</a></span>
  551.                       <span>Cell: 405-880-5053</span>
  552.                     </div>
  553.                   </td>
  554.                 </tr>
  555.               </table>
  556.             </>
  557.           }
  558.         }}
  559.       </>
  560.     }
  561.    
  562. }
  563.  
  564. ================
  565. File: gmm_client/src/pages/dashboard.rs
  566. ================
  567. use leptos::*; // Import the Leptos framework
  568. use std::vec;
  569. use chrono::NaiveDate;
  570. use crate::components::table::*; // Import the Table component
  571. use crate::tables::dashboardjibs::resource::DashboardJibsResource; // Import the DashboardJibsResource struct
  572. use crate::tables::dashboardrevenue::resource::DashboardRevenueResource; // Import the DashboardRevenueResource struct
  573. use crate::components::table_skeleton::TableSkeleton; // Import the TableSkeleton component
  574.  
  575.  
  576. #[derive(Clone, Debug)]
  577. pub struct FilterDashboard {
  578.     pub operator: String,
  579.     pub payment_status: String,
  580.     pub month_from: String,
  581.     pub year_from: String,
  582.     pub month_to: String,
  583.     pub year_to: String,
  584. }
  585.  
  586. #[component]
  587. pub fn Dashboard() -> impl IntoView {
  588.     let dashboard_resource = DashboardJibsResource::new();
  589.     let dashboard_revenue = DashboardRevenueResource::new();
  590.  
  591.     let (filter, set_filter) = create_signal(FilterDashboard {
  592.         operator:    String::new(),
  593.         payment_status: "All".to_string(),
  594.         month_from: "Jan".to_string(),
  595.         year_from:  "2015".to_string(),
  596.         month_to:   "Dec".to_string(),
  597.         year_to:    "2025".to_string(),
  598.     });
  599.    
  600.     let (error_message, set_error_message) = create_signal(None::<String>);
  601.  
  602.     let months = vec![
  603.         "Jan", "Feb", "Mar", "Apr", "May", "Jun",
  604.         "Jul", "Aug", "Sep", "Oct", "Nov", "Dec",
  605.     ];
  606.     let years = vec![
  607.         "2025", "2024", "2023", "2022", "2021",
  608.     ];
  609.     let payment_options = vec![
  610.         "All".to_string(),
  611.         "Approved".to_string(),
  612.         "Not Approved".to_string(),
  613.     ];
  614.  
  615.     let months_clone = months.clone();
  616.     let years_clone  = years.clone();
  617.  
  618.     let filtered_dashboard_jibs = create_memo(move |_| {
  619.         let current_filter = filter.get();
  620.         let from = build_ym(&current_filter.year_from, &current_filter.month_from);
  621.         let to   = build_ym(&current_filter.year_to, &current_filter.month_to);
  622.  
  623.         dashboard_resource
  624.         .rows
  625.         .get()
  626.         .map(|pages| {
  627.             pages
  628.             .iter()
  629.             .flat_map(|page| page.iter())
  630.             .filter(|dashboard| {
  631.                 let date = &dashboard.month;
  632.                 (current_filter.operator.is_empty()
  633.                 || dashboard.operator_name.to_lowercase().contains(&current_filter.operator.to_lowercase()))
  634.                 && (current_filter.payment_status == "All"
  635.                     || (current_filter.payment_status == "Approved"
  636.                         && dashboard.jib_amount > 0.0)
  637.                     || (current_filter.payment_status == "Not Approved"
  638.                         && dashboard.jib_amount <= 0.0))
  639.                 && (from <= *date && *date <= to)
  640.             })
  641.             .cloned()
  642.             .collect::<Vec<_>>()
  643.         })
  644.     });
  645.  
  646.     let filtered_dashboard_revenue = create_memo(move |_| {
  647.         let current_filter = filter.get();
  648.         let from = build_ym(&current_filter.year_from, &current_filter.month_from);
  649.         let to   = build_ym(&current_filter.year_to, &current_filter.month_to);
  650.  
  651.         dashboard_revenue
  652.         .rows
  653.         .get()
  654.         .map(|pages| {
  655.             pages
  656.             .iter()
  657.             .flat_map(|page| page.iter())
  658.             .filter(|revenue| {
  659.                 let date = revenue.payment_date.clone();
  660.                 (current_filter.operator.is_empty()
  661.                     || revenue.operator_purchaser.to_lowercase().contains(&current_filter.operator.to_lowercase()))
  662.                 && (from <= date && date <= to)
  663.             })
  664.             .cloned()
  665.             .collect::<Vec<_>>()
  666.         })
  667.     });
  668.  
  669.     fn is_invalid_range(filter: &FilterDashboard) -> bool {
  670.         let parse = |m: &str, y: &str| {
  671.             let num = match m {
  672.                 "Jan" => 1,  "Feb" => 2,  "Mar" => 3,  "Apr" => 4,
  673.                 "May" => 5,  "Jun" => 6,  "Jul" => 7,  "Aug" => 8,
  674.                 "Sep" => 9,  "Oct" => 10, "Nov" => 11, "Dec" => 12,
  675.                 _     => 1,
  676.             };
  677.             NaiveDate::from_ymd_opt(y.parse().unwrap_or(2000), num, 1).unwrap()
  678.         };
  679.         parse(&filter.month_from, &filter.year_from)
  680.             > parse(&filter.month_to,   &filter.year_to)
  681.     }
  682.  
  683.     create_effect(move |_| {
  684.         let current = filter.get();
  685.         if is_invalid_range(&current) {
  686.             set_error_message.set(Some("The 'From' date cannot be after the 'To' date.".into()));
  687.         } else {
  688.             set_error_message.set(None);
  689.         }
  690.     });
  691.  
  692.     view! {
  693.         <div class="tables">
  694.             { move || {
  695.                 error_message.get().as_ref().map(|msg| view! {
  696.                     <div
  697.                         class="alert-danger push-left d-flex align-items-center justify-content-between mb-3 w-75"
  698.                         role="alert"
  699.                     >
  700.                         <img src="/error-icon.png" class="icon-sm" alt="Error" />
  701.                         <span class="alert-message">{ msg }</span>
  702.                         <img
  703.                             src="/close-icon.png"
  704.                             class="icon-sm clickable"
  705.                             alt="Close"
  706.                             on:click=move |_| set_error_message.set(None)
  707.                         />
  708.                     </div>
  709.                 })
  710.             }}
  711.             <h2 class="title-guardian-content">Most Recent</h2>
  712.  
  713.             <div class="d-flex flex-sm-row align-items-center justify-content-start gap-2">
  714.                 <div class="d-flex align-items-center search-operator-mobile">
  715.                     <input
  716.                         type="search"
  717.                         placeholder="Filter by Operator Name"
  718.                         class="form-control w-auto"
  719.                         on:input=move |ev| {
  720.                             let v = event_target_value(&ev);
  721.                             set_filter.update(|f| f.operator = v);
  722.                         }
  723.                         prop:value=filter.get().operator.clone()
  724.                     />
  725.                 </div>
  726.                 <div class="d-flex align-items-center gap-2">
  727.                     <select
  728.                         class="form-select w-auto"
  729.                         on:change=move |e| {
  730.                             let v = event_target_value(&e);
  731.                             set_filter.update(|f| f.payment_status = v);
  732.                         }
  733.                         prop:value=filter.get().payment_status.clone()
  734.                     >
  735.                         { payment_options.iter().map(|opt| view! {
  736.                             <option value={opt.clone()}>{opt}</option>
  737.                         }).collect_view() }
  738.                     </select>
  739.                 </div>
  740.  
  741.                 <div class="d-flex align-items-center gap-2">
  742.                     <p class="fs-06">"from"</p>
  743.                     <select
  744.                         class="form-select w-auto"
  745.                         on:change=move |e| {
  746.                             let v = event_target_value(&e);
  747.                             set_filter.update(|f| f.month_from = v);
  748.                         }
  749.                         prop:value=filter.get().month_from.clone()
  750.                     >
  751.                         { months.iter().map(|m| view! {
  752.                             <option value={m.to_string()}>{m.to_string()}</option>
  753.                         }).collect_view() }
  754.                     </select>
  755.  
  756.                     <select
  757.                         class="form-select w-auto"
  758.                         on:change=move |e| {
  759.                             let v = event_target_value(&e);
  760.                             set_filter.update(|f| f.year_from = v);
  761.                         }
  762.                         prop:value=filter.get().year_from.clone()
  763.                     >
  764.                         { years.iter().map(|y| view! {
  765.                             <option value={y.to_string()}>{y.to_string()}</option>
  766.                         }).collect_view() }
  767.                     </select>
  768.                 </div>
  769.  
  770.                 <div class="d-flex align-items-center gap-2">
  771.                     <p class="fs-06">"to"</p>
  772.                     <select
  773.                         class="form-select w-auto"
  774.                         on:change=move |e| {
  775.                             let v = event_target_value(&e);
  776.                             set_filter.update(|f| f.month_to = v);
  777.                         }
  778.                         prop:value=filter.get().month_to.clone()
  779.                     >
  780.                         { months_clone.iter().map(|m| view! {
  781.                             <option value={m.to_string()}>{m.to_string()}</option>
  782.                         }).collect_view() }
  783.                     </select>
  784.  
  785.                     <select
  786.                         class="form-select w-auto"
  787.                         on:change=move |e| {
  788.                             let v = event_target_value(&e);
  789.                             set_filter.update(|f| f.year_to = v);
  790.                         }
  791.                         prop:value=filter.get().year_to.clone()
  792.                     >
  793.                         { years_clone.iter().map(|y| view! {
  794.                             <option value={y.to_string()}>{y.to_string()}</option>
  795.                         }).collect_view() }
  796.                     </select>
  797.                 </div>
  798.             </div>
  799.  
  800.             <h2 class="title-guardian-footer">
  801.                 JIBs to pay
  802.             </h2>
  803.             <p class="font-georgia mb-0">
  804.                 JIBs received in the last 30 days. Please click  Yes or No button to process them.
  805.             </p>
  806.  
  807.             <Suspense fallback={move || view! {
  808.                 <div>
  809.                     <TableSkeleton />
  810.                 </div>
  811.             }}>
  812.                 {move ||
  813.                     match filtered_dashboard_jibs.get() {
  814.                         Some(dashboards) => {
  815.                             log::info!("Fetched dashboards: {:?}", dashboards);
  816.  
  817.                             let approval_states: Vec<RwSignal<Option<bool>>> = dashboards
  818.                                 .iter()
  819.                                 .map(|_| create_rw_signal(None))
  820.                                 .collect();
  821.  
  822.                             let data = TableData {
  823.                                 headers: vec![
  824.                                     view! { <p>"Operator Name"</p> }.into_view(),
  825.                                     view! { <p>"JIB Amount"</p> }.into_view(),
  826.                                     view! { <p>"Netted Amount"</p> }.into_view(),
  827.                                     view! { <p>"Difference"</p> }.into_view(),
  828.                                     view! { <p>"Month"</p> }.into_view(),
  829.                                     view! { <p>"Approve to Pay"</p> }.into_view(),
  830.                                 ],
  831.                                 rows: dashboards.iter().enumerate().map(|(index, dashboard)| {
  832.                                     let approval = approval_states[index];
  833.                                    
  834.                                     let action_cell = move || {
  835.                                         {
  836.                                             if dashboard.jib_amount > 0.0 {
  837.                                                 view! {
  838.                                                     <>
  839.                                                         <label class="checkbox-label">
  840.                                                             <input
  841.                                                                 id="approved"
  842.                                                                 name="approved"
  843.                                                                 type="radio"
  844.                                                                 checked={move || approval.get() == Some(true)}
  845.                                                                 on:change={move |_| {
  846.                                                                     if approval.get() == Some(true) {
  847.                                                                         approval.set(None);
  848.                                                                     } else {
  849.                                                                         approval.set(Some(true));
  850.                                                                     }
  851.                                                                 }}
  852.                                                                 disabled={move || approval.get() == Some(true)}
  853.                                                             />
  854.                                                             {
  855.                                                                 move || if approval.get() == Some(true) {
  856.                                                                     "Approved"
  857.                                                                 } else {
  858.                                                                     "Yes"
  859.                                                                 }
  860.                                                             }
  861.                                                         </label>
  862.                                                         <label class="checkbox-label">
  863.                                                             <input
  864.                                                                 id="approved"
  865.                                                                 name="approved"
  866.                                                                 type="radio"
  867.                                                                 checked={move || approval.get() == Some(false)}
  868.                                                                 on:change={move |_| {
  869.                                                                     if approval.get() == Some(false) {
  870.                                                                         approval.set(None);
  871.                                                                     } else {
  872.                                                                         approval.set(Some(false));
  873.                                                                     }
  874.                                                                 }}
  875.                                                                 disabled={move || approval.get() == Some(false)}
  876.                                                             />
  877.                                                             {
  878.                                                                 move || if approval.get() == Some(false) {
  879.                                                                     "Not Approved"
  880.                                                                 } else {
  881.                                                                     "No"
  882.                                                                 }
  883.                                                             }
  884.                                                         </label>
  885.                                                     </>
  886.                                                 }.into_view()
  887.                                             } else {
  888.                                                 view! { <button class="d-none" disabled=true></button> }.into_view()
  889.                                             }
  890.                                         }
  891.                                     };
  892.                                     vec![
  893.                                         view! { <p>{dashboard.operator_name.clone()}</p> }.into_view(),
  894.                                         view! { <p>{dashboard.jib_amount.to_string()}</p> }.into_view(),
  895.                                         view! { <p>{dashboard.netted_amount.map_or("N/A".to_string(), |n| n.to_string())}</p> }.into_view(),
  896.                                         view! { <p>{dashboard.difference.clone()}</p> }.into_view(),
  897.                                         view! { <p>{dashboard.month.clone()}</p> }.into_view(),
  898.                                         view! {
  899.                                             <div class="checkbox-group">
  900.                                                 {action_cell()}
  901.                                             </div>
  902.                                         }.into_view(),
  903.                                     ]
  904.                                 }).collect::<Vec<_>>(),
  905.                                 links: vec![Some(vec!["https://www.google.com".to_string(); 4])],
  906.                                 has_totals: false,
  907.                             };
  908.  
  909.                             view! {
  910.                                 <div>
  911.                                     <Table data={data} />
  912.                                 </div>
  913.                             }
  914.                         },
  915.                         None => view! {
  916.                             <div>
  917.                                 <TableSkeleton />
  918.                             </div>
  919.                         },
  920.                     }
  921.                 }
  922.             </Suspense>
  923.  
  924.             <h2 class="title-guardian-footer">Lease Bonuses, Settlements, and Shut-Ins</h2>
  925.             <p class="font-georgia mb-0">
  926.                 Lease bonuses, settlements, and shut-in payments received in the last 30 days.
  927.             </p>
  928.  
  929.             <Suspense fallback={move || view! {
  930.                 <div>
  931.                     <TableSkeleton />
  932.                 </div>
  933.             }}>
  934.                 {move ||
  935.                     match filtered_dashboard_revenue.get() {
  936.                         Some(revenues) => {
  937.                             log::info!("Fetched revenues: {:?}", revenues);
  938.  
  939.                             let data = TableData {
  940.                                 headers: vec![
  941.                                     view! { <p>"Operator Purchaser"</p> }.into_view(),
  942.                                     view! { <p>"Gross Revenue"</p> }.into_view(),
  943.                                     view! { <p>"Taxes"</p> }.into_view(),
  944.                                     view! { <p>"Deductions"</p> }.into_view(),
  945.                                     view! { <p>"Net Revenue"</p> }.into_view(),
  946.                                     view! { <p>"Payment Amount"</p> }.into_view(),
  947.                                     view! { <p>"Payment Date"</p> }.into_view(),
  948.                                 ],
  949.                                 rows: revenues.iter().map(|revenue| {
  950.                                     vec![
  951.                                         view! { <p>{revenue.operator_purchaser.clone()}</p> }.into_view(),
  952.                                         view! { <p>{revenue.gross_revenue.map_or("N/A".to_string(), |g| g.to_string())}</p> }.into_view(),
  953.                                         view! { <p>{revenue.taxes.map_or("N/A".to_string(), |t| t.to_string())}</p> }.into_view(),
  954.                                         view! { <p>{revenue.deductions.map_or("N/A".to_string(), |d| d.to_string())}</p> }.into_view(),
  955.                                         view! { <p>{revenue.net_revenue.map_or("N/A".to_string(), |n| n.to_string())}</p> }.into_view(),
  956.                                         view! { <p>{revenue.payment_amount.map_or("N/A".to_string(), |pa| pa.to_string())}</p> }.into_view(),
  957.                                         view! { <p>{revenue.payment_date.clone()}</p> }.into_view(),
  958.                                     ]
  959.                                 }).collect::<Vec<_>>(),
  960.                                 links: vec![Some(vec!["https://www.google.com".to_string(); 4])],
  961.                                 has_totals: false,
  962.                             };
  963.  
  964.                             view! {
  965.                                 <div>
  966.                                     <Table data={data} />
  967.                                 </div>
  968.                             }
  969.                         },
  970.                         None => view! {
  971.                             <div>
  972.                                 <TableSkeleton />
  973.                             </div>
  974.                         },
  975.                     }
  976.                 }
  977.             </Suspense>
  978.         </div>
  979.     }
  980. }
  981.  
  982. fn build_ym(year: &str, month_str: &str) -> String {
  983.     format!("{}-{}", year, month_str_to_number(month_str))
  984. }
  985.  
  986. fn month_str_to_number(m: &str) -> &str {
  987.     match m {
  988.         "Jan" => "01", "Feb" => "02", "Mar" => "03", "Apr" => "04",
  989.         "May" => "05", "Jun" => "06", "Jul" => "07", "Aug" => "08",
  990.         "Sep" => "09", "Oct" => "10", "Nov" => "11", "Dec" => "12",
  991.         _     => "00",
  992.     }
  993. }
  994.  
  995. ================
  996. File: gmm_client/src/pages/incoming.rs
  997. ================
  998. use crate::components::filter_tables::*;
  999. use crate::components::table::*;
  1000. use crate::components::table_skeleton::TableSkeleton;
  1001. use crate::tables::incominglocation::resource::IncomingLocationResource;
  1002. use crate::tables::incomingproducts::resource::IncomingProductsResource;
  1003. use crate::tables::incomingtable1::resource::IncomingTable1Resource;
  1004. use crate::tables::incomingtable2::resource::IncomingTable2Resource;
  1005.  
  1006. use leptos::*;
  1007.  
  1008. #[component]
  1009. pub fn Incoming() -> impl IntoView {
  1010.     let incoming_by_operator = IncomingTable1Resource::new();
  1011.     let incoming_by_from_lease_bonuses = IncomingTable2Resource::new();
  1012.  
  1013.     let incoming_products_resource = IncomingProductsResource::new();
  1014.     let incoming_location_resource = IncomingLocationResource::new();
  1015.  
  1016.     view! {
  1017.       <div class="tables">
  1018.         <h2 class="title-guardian-content">"Incoming"</h2>
  1019.         <FilterTables />
  1020.  
  1021.         <p class="font-georgia mb-0">
  1022.           "This table contains revenue by operator."
  1023.         </p>
  1024.  
  1025.         <Suspense fallback={move || view!
  1026.             {
  1027.                 <div>
  1028.                     <TableSkeleton />
  1029.                 </div>
  1030.             }
  1031.         }>
  1032.             {
  1033.                 move ||
  1034.                 // Check the result of fetching incoming data
  1035.                 match incoming_by_operator.revenue_rows.get() {
  1036.                     // If incoming data is successfully fetched
  1037.                     Some(Ok(incoming)) => {
  1038.                         // Define the table data structure
  1039.                         let data_revenue_by_operator = TableData {
  1040.                             // Table headers
  1041.                             headers: vec![
  1042.                                 view! { <p class="max-w-300">"Operator"</p> }.into_view(),
  1043.                                 view! { <p>"Gross"<br />"Revenue"</p> }.into_view(),
  1044.                                 view! { <p>"Taxes"</p> }.into_view(),
  1045.                                 view! { <p>"Deductions"</p> }.into_view(),
  1046.                                 view! { <p>"Net" <br/> "Revenue"</p> }.into_view(),
  1047.                                 view! { <p>"Payment" <br/> "Amount"</p> }.into_view(),
  1048.                                 view! { <p>"Payment" <br/> "Date"</p> }.into_view(),
  1049.                                 view! { <p>"Depletion" <br/> "15%"</p> }.into_view(),
  1050.                                 view! { <p>"Net Post-"<br />"Depletion" <br/> "15%"</p> }.into_view(),
  1051.                                 view! { <p>"Depletion" <br/> "27.5%"</p> }.into_view(),
  1052.                                 view! { <p>"Net Post-"<br />"Depletion" <br/> "27.5%"</p> }.into_view(),
  1053.                             ],
  1054.                             // Table rows mapped from the fetched incoming data
  1055.                             rows: incoming.iter().enumerate().take(100).map(|(_index, incoming)| {
  1056.                                 vec![
  1057.                                     view! { <p class="max-w-300">{incoming.operator_name.clone()}</p> }.into_view(),
  1058.                                     view! { <p class="max-w-200">{incoming.gross_revenue.clone()}</p> }.into_view(),
  1059.  
  1060.                                     view! { <p>{incoming.taxes.clone()}</p> }.into_view(),
  1061.                                     view! { <p>{incoming.deductions.clone()}</p> }.into_view(),
  1062.                                     view! { <p>{incoming.net_revenue.clone()}</p> }.into_view(),
  1063.                                     view! { <p>{incoming.payment_amount.clone()}</p> }.into_view(),
  1064.                                     view! { <p>{incoming.payment_date.clone()}</p> }.into_view(),
  1065.                                     view! { <p>{incoming.depletion_15.clone()}</p> }.into_view(),
  1066.                                     view! { <p>{incoming.net_post_depletion_15.clone()}</p> }.into_view(),
  1067.                                     view! { <p>{incoming.depletion_275.clone()}</p> }.into_view(),
  1068.                                     view! { <p>{incoming.net_post_depletion_275.clone()}</p> }.into_view(),
  1069.                                 ]
  1070.                             }).collect::<Vec<_>>(),
  1071.                             // Links for each row (example with Google links)
  1072.                             links: vec![Some(vec!["https://www.google.com".to_string(); 4])],
  1073.                             // No totals to display in the table
  1074.                             has_totals: false,
  1075.                         };
  1076.                         // Render the table with the provided data
  1077.                         view! {
  1078.                             <div>
  1079.                                 <Table data={data_revenue_by_operator} />
  1080.                             </div>
  1081.                         }
  1082.                     },
  1083.                     // If an error occurs while fetching data
  1084.                     Some(Err(_)) => {
  1085.                         log::error!("Error fetching incoming {}", incoming_by_operator.revenue_rows.get().unwrap().err().unwrap());
  1086.                         view! { <div><p>"Error..."</p></div> }
  1087.                     },
  1088.                     // If no data is available (still loading)
  1089.                     None => view! {
  1090.                         <div>
  1091.                             <TableSkeleton />
  1092.                         </div>
  1093.                     },
  1094.                 }
  1095.             }
  1096.         </Suspense>
  1097.  
  1098.         <p class="font-georgia mb-0">
  1099.           "This table contains revenue from lease bonuses, settlements and shut-ins."
  1100.         </p>
  1101.  
  1102.         <Suspense fallback={move || view!
  1103.             {
  1104.                 <div>
  1105.                     <TableSkeleton />
  1106.                 </div>
  1107.             }
  1108.         }>
  1109.             {
  1110.                 move ||
  1111.                 // Check the result of fetching incoming data
  1112.                 match incoming_by_from_lease_bonuses.rows.get() {
  1113.                     // If incoming data is successfully fetched
  1114.                     Some(Ok(incoming)) => {
  1115.                         // Define the table data structure
  1116.                         let data_revenue_from_lease_bonuses = TableData {
  1117.                             // Table headers
  1118.                             headers: vec![
  1119.                                 view! { <p class="max-w-300">"Operator"</p> }.into_view(),
  1120.                                 view! { <p>"Description"</p> }.into_view(),
  1121.                                 view! { <p>"Gross"<br />"Revenue"</p> }.into_view(),
  1122.                                 view! { <p>"Taxes"</p> }.into_view(),
  1123.                                 view! { <p>"Deductions"</p> }.into_view(),
  1124.                                 view! { <p>"Net" <br/> "Revenue"</p> }.into_view(),
  1125.                                 view! { <p>"Payment" <br/> "Amount"</p> }.into_view(),
  1126.                                 view! { <p>"Payment" <br/> "Date"</p> }.into_view(),
  1127.                             ],
  1128.                             // Table rows mapped from the fetched incoming data
  1129.                             rows: incoming.iter().enumerate().take(100).map(|(_index, incoming)| {
  1130.                                 vec![
  1131.                                     view! { <p class="max-w-300">{incoming.operator_name.clone()}</p> }.into_view(),
  1132.                                     view! { <p>{incoming.description.clone()}</p> }.into_view(),
  1133.  
  1134.                                     view! { <p>{incoming.gross_revenue.clone()}</p> }.into_view(),
  1135.                                     view! { <p>{incoming.taxes.clone()}</p> }.into_view(),
  1136.                                     view! { <p>{incoming.deductions.clone()}</p> }.into_view(),
  1137.                                     view! { <p>{incoming.net_revenue.clone()}</p> }.into_view(),
  1138.                                     view! { <p>{incoming.payment_amount.clone()}</p> }.into_view(),
  1139.                                     view! { <p>{incoming.payment_date.clone()}</p> }.into_view(),
  1140.                                 ]
  1141.                             }).collect::<Vec<_>>(),
  1142.                             // Links for each row (example with Google links)
  1143.                             links: vec![Some(vec!["https://www.google.com".to_string(); 4])],
  1144.                             // No totals to display in the table
  1145.                             has_totals: false,
  1146.                         };
  1147.                         // Render the table with the provided data
  1148.                         view! {
  1149.                             <div>
  1150.                                 <Table data={data_revenue_from_lease_bonuses} />
  1151.                             </div>
  1152.                         }
  1153.                     },
  1154.                     // If an error occurs while fetching data
  1155.                     Some(Err(_)) => {
  1156.                         log::error!("Error fetching incoming {}", incoming_by_from_lease_bonuses.rows.get().unwrap().err().unwrap());
  1157.                         view! { <div><p>"Error..."</p></div> }
  1158.                     },
  1159.                     // If no data is available (still loading)
  1160.                     None => view! {
  1161.                         <div>
  1162.                             <TableSkeleton />
  1163.                         </div>
  1164.                     },
  1165.                 }
  1166.             }
  1167.         </Suspense>
  1168.  
  1169.         <h2 class="title-guardian-footer">"Location"</h2>
  1170.         <p class="font-georgia mb-0">"Wells by State & County."</p>
  1171.  
  1172.         <Suspense fallback={move || view!
  1173.             {
  1174.                 <div>
  1175.                     <TableSkeleton />
  1176.                 </div>
  1177.             }
  1178.         }>
  1179.             {
  1180.                 move ||
  1181.                 // Check the result of fetching incoming location data
  1182.                 match incoming_location_resource.revenue_rows.get() {
  1183.                     // If incoming location data is successfully fetched
  1184.                     Some(Ok(location)) => {
  1185.                         // Define the table data structure
  1186.                         let data_location = TableData {
  1187.                             // Table headers
  1188.                             headers: vec![
  1189.                                 view! { <p>"State"</p> }.into_view(),
  1190.                                 view! { <p>"County"</p> }.into_view(),
  1191.                                 view! { <p>"Gross"<br />"Revenue"</p> }.into_view(),
  1192.                                 view! { <p>"Taxes"</p> }.into_view(),
  1193.                                 view! { <p>"Deductions"</p> }.into_view(),
  1194.                                 view! { <p>"Net" <br/> "Revenue"</p> }.into_view(),
  1195.                                 view! { <p>"Payment" <br/> "Date"</p> }.into_view(),
  1196.                             ],
  1197.                             // Table rows mapped from the fetched location data
  1198.                             rows: location.iter().enumerate().take(100).map(|(_index, location)| {
  1199.                                 vec![
  1200.                                     view! { <p>{location.state.clone()}</p> }.into_view(),
  1201.                                     view! { <p>{location.county.clone()}</p> }.into_view(),
  1202.                                     view! { <p>{location.gross_revenue.clone()}</p> }.into_view(),
  1203.                                     view! { <p>{location.taxes.clone()}</p> }.into_view(),
  1204.                                     view! { <p>{location.deductions.clone()}</p> }.into_view(),
  1205.                                     view! { <p>{location.net_revenue.clone()}</p> }.into_view(),
  1206.                                     view! { <p>{location.payment_date.clone()}</p> }.into_view(),
  1207.                                 ]
  1208.                             }).collect::<Vec<_>>(),
  1209.                             // Links for each row (example with Google links)
  1210.                             links: vec![Some(vec!["https://www.google.com".to_string(); 4])],
  1211.                             // No totals to display in the table
  1212.                             has_totals: false,
  1213.                         };
  1214.                         // Render the table with the provided data
  1215.                         view! {
  1216.                             <div>
  1217.                                 <Table data={data_location} />
  1218.                             </div>
  1219.                         }
  1220.                     },
  1221.                     // If an error occurs while fetching data
  1222.                     Some(Err(_)) => {
  1223.                         log::error!("Error fetching location {}", incoming_location_resource.revenue_rows.get().unwrap().err().unwrap());
  1224.                         view! { <div><p>"Error..."</p></div> }
  1225.                     },
  1226.                     // If no data is available (still loading)
  1227.                     None => view! {
  1228.                         <div>
  1229.                             <TableSkeleton />
  1230.                         </div>
  1231.                     },
  1232.                 }
  1233.             }
  1234.         </Suspense>
  1235.  
  1236.         <h2 class="title-guardian-footer">"Products"</h2>
  1237.         <Suspense fallback={move || view!
  1238.             {
  1239.                 <div>
  1240.                     <TableSkeleton />
  1241.                 </div>
  1242.             }
  1243.         }>
  1244.             {move ||
  1245.                 // Check the result of fetching incoming products data
  1246.                 match incoming_products_resource.revenue_rows.get() {
  1247.                     // If incoming products data is successfully fetched
  1248.                     Some(Ok(products)) => {
  1249.                         // Define the table data structure
  1250.                         let data_products = TableData {
  1251.                             // Table headers
  1252.                             headers: vec![
  1253.                                 view! { <p class="max-w-300">"Product"</p> }.into_view(),
  1254.                                 view! { <p class="max-w-200">"Gross"<br />"Revenue"</p> }.into_view(),
  1255.                                 view! { <p>"Taxes"</p> }.into_view(),
  1256.                                 view! { <p>"Deductions"</p> }.into_view(),
  1257.                                 view! { <p>"Net" <br/> "Revenue"</p> }.into_view(),
  1258.                                 view! { <p>"Payment" <br/> "Date"</p> }.into_view(),
  1259.                             ],
  1260.                             // Table rows mapped from the fetched products
  1261.                             rows: products.iter().enumerate().take(100).map(|(_index, product)| {
  1262.                                 vec![
  1263.                                     view! { <p class="max-w-300">{product.product.clone()}</p> }.into_view(),
  1264.  
  1265.  
  1266.                                     view! { <p class="max-w-200">{product.gross_revenue.clone()}</p> }.into_view(),
  1267.  
  1268.                                     view! { <p>{product.taxes.clone()}</p> }.into_view(),
  1269.                                     view! { <p>{product.deductions.clone()}</p> }.into_view(),
  1270.                                     view! { <p>{product.net_revenue.clone()}</p> }.into_view(),
  1271.                                     view! { <p>{product.payment_date.clone()}</p> }.into_view(),
  1272.                                 ]
  1273.                             }).collect::<Vec<_>>(),
  1274.                             // Links for each row (example with Google links)
  1275.                             links: vec![Some(vec!["https://www.google.com".to_string(); 4])],
  1276.                             // No totals to display in the table
  1277.                             has_totals: false,
  1278.                         };
  1279.                         // Render the table with the provided data
  1280.                         view! {
  1281.                             <div>
  1282.                                 <Table data={data_products} />
  1283.                             </div>
  1284.                         }
  1285.                     },
  1286.                     // If an error occurs while fetching data
  1287.                     Some(Err(_)) => {
  1288.                         log::error!("Error fetching products {}", incoming_products_resource.revenue_rows.get().unwrap().err().unwrap());
  1289.                         view! { <div><p>"Error..."</p></div> }
  1290.                     },
  1291.                     // If no data is available (still loading)
  1292.                     None => view! {
  1293.                         <div>
  1294.                             <TableSkeleton />
  1295.                         </div>
  1296.                     },
  1297.                 }
  1298.             }
  1299.         </Suspense>
  1300.       </div>
  1301.     }
  1302. }
  1303.  
  1304. ================
  1305. File: gmm_client/src/pages/jibs.rs
  1306. ================
  1307. use leptos::*;
  1308.  
  1309. use crate::components::filter_tables::*;
  1310. use crate::components::table::*;
  1311. use crate::components::table_skeleton::TableSkeleton;
  1312. use crate::tables::jibdetails::resource::JibDetailsResource;
  1313. use crate::tables::jibnetting::resource::JibNettingResource;
  1314. use crate::tables::jibsummary::resource::JibSummaryResource;
  1315. use crate::tables::revjibdetails::resource::RevJibDetailsResource;
  1316. use crate::tables::revjibsummary::resource::RevJibSummaryResource;
  1317.  
  1318. #[component]
  1319. pub fn Jibs() -> impl IntoView {
  1320.     let jib_details_resource = JibDetailsResource::new();
  1321.     let jib_netting_resource = JibNettingResource::new();
  1322.     let jib_summary_resource = JibSummaryResource::new();
  1323.  
  1324.     let jib_rev_jib_details = RevJibDetailsResource::new();
  1325.     let jib_rev_jib_summary = RevJibSummaryResource::new();
  1326.  
  1327.     view! {
  1328.       <div class="tables">
  1329.         <h2 class="title-guardian-content">Joint Interest Billings</h2>
  1330.  
  1331.         <FilterTables />
  1332.  
  1333.         <h2 class="title-guardian-footer">Jib Netting</h2>
  1334.         <p class="font-georgia mb-0">The amount owed on your joint interest billing invoice and deducted from your revenue.</p>
  1335.         <Suspense fallback={move || view!
  1336.             {
  1337.                 <div>
  1338.                     <TableSkeleton />
  1339.                 </div>
  1340.             }
  1341.         }>
  1342.             {move ||
  1343.                 // Check the result of fetching jib netting data
  1344.                 match jib_netting_resource.revenue_rows.get() {
  1345.                     // If jib netting data is successfully fetched
  1346.                     Some(Ok(jib_netting)) => {
  1347.                         // Define the table data structure
  1348.                         let dataJibNetting = TableData {
  1349.                             // Table headers
  1350.                             headers: vec![
  1351.                                 view! { <p class="max-w-300">"Operator"</p> }.into_view(),
  1352.                                 view! { <p class="max-w-200">"Payment" <br/> "Date"</p> }.into_view(),
  1353.                                 view! { <p class="max-w-200">"Netted Revenue"</p> }.into_view(),
  1354.                             ],
  1355.                             // Table rows mapped from the fetched jib netting
  1356.                             rows: jib_netting.iter().map(|jib_netting| {
  1357.                                 vec![
  1358.                                     view! { <p>{jib_netting.operator_purchaser.clone()}</p> }.into_view(),
  1359.                                     view! { <p>{jib_netting.check_date.clone()}</p> }.into_view(),
  1360.                                     view! { <p>{jib_netting.share_net_revenue.clone()}</p> }.into_view(),
  1361.                                 ]
  1362.                             }).collect(),
  1363.                             links: vec![Some(vec!["https://www.google.com".to_string(); 4])],
  1364.                             has_totals: false,
  1365.                         };
  1366.                         // Render the table with the provided data
  1367.                         view! {
  1368.                             <div>
  1369.                                 <Table data={dataJibNetting} />
  1370.                             </div>
  1371.                         }
  1372.                     },
  1373.                     // If an error occurs while fetching data
  1374.                     Some(Err(_)) => {
  1375.                         log::error!("Error fetching jib netting {}", jib_netting_resource.revenue_rows.get().unwrap().err().unwrap());
  1376.                         view! { <div><p>"Error..."</p></div> }
  1377.                     },
  1378.                     // If no data is available (still loading)
  1379.                     None => view! {
  1380.                         <div>
  1381.                             <TableSkeleton />
  1382.                         </div>
  1383.                     },
  1384.                 }
  1385.             }
  1386.         </Suspense>
  1387.  
  1388.         <h2 class="title-guardian-footer">Jib Summary</h2>
  1389.         <p class="font-georgia mb-0">Please see all your JIBs listed here.</p>
  1390.         <Suspense fallback={move || view!
  1391.             {
  1392.                 <div>
  1393.                     <TableSkeleton />
  1394.                 </div>
  1395.             }
  1396.         }>
  1397.             {move ||
  1398.                 // Check the result of fetching jib summary data
  1399.                 match jib_summary_resource.revenue_rows.get() {
  1400.                     // If jib summary data is successfully fetched
  1401.                     Some(Ok(jib_summary)) => {
  1402.                         // Define the table data structure
  1403.                         let dataJibsSummary = TableData {
  1404.                             // Table headers
  1405.                             headers: vec![
  1406.                                 view! { <p class="max-w-300">"Operator"</p> }.into_view(),
  1407.                                 view! { <p class="max-w-200">"Payment" <br/> "Date"</p> }.into_view(),
  1408.                                 view! { <p class="max-w-200">"Reference Number"</p> }.into_view(),
  1409.                                 view! { <p class="max-w-200">"Amount"</p> }.into_view(),
  1410.                             ],
  1411.                             // Table rows mapped from the fetched jib summary
  1412.                             rows: jib_summary.iter().map(|jib_summary| {
  1413.                                 vec![
  1414.                                     view! { <p class="max-w-300">{jib_summary.payor.clone()}</p> }.into_view(),
  1415.                                     view! { <p class="max-w-200">{jib_summary.payment_date.clone()}</p> }.into_view(),
  1416.                                     view! { <p class="max-w-200">{jib_summary.invoice_number.clone()}</p> }.into_view(),
  1417.                                     view! { <p class="max-w-200">{jib_summary.total_amount.clone()}</p> }.into_view()
  1418.                                 ]
  1419.                             }).collect(),
  1420.                             links: vec![Some(vec!["https://www.google.com".to_string(); 4])],
  1421.                             has_totals: false,
  1422.                         };
  1423.                         // Render the table with the provided data
  1424.                         view! {
  1425.                             <div>
  1426.                                 <Table data={dataJibsSummary} />
  1427.                             </div>
  1428.                         }
  1429.                     },
  1430.                     // If an error occurs while fetching data
  1431.                     Some(Err(_)) => {
  1432.                         log::error!("Error fetching jib summary {}", jib_summary_resource.revenue_rows.get().unwrap().err().unwrap());
  1433.                         view! { <div><p>"Error..."</p></div> }
  1434.                     },
  1435.                     // If no data is available (still loading)
  1436.                     None => view! {
  1437.                         <div>
  1438.                             <TableSkeleton />
  1439.                         </div>
  1440.                     },
  1441.                 }
  1442.             }
  1443.         </Suspense>
  1444.  
  1445.         <h2 class="title-guardian-footer">Jib Details</h2>
  1446.         <Suspense fallback={move || view!
  1447.             {
  1448.                 <div>
  1449.                     <TableSkeleton />
  1450.                 </div>
  1451.             }
  1452.         }>
  1453.             {move ||
  1454.                 // Check the result of fetching jib details data
  1455.                 match jib_details_resource.revenue_rows.get() {
  1456.                     // If jib details data is successfully fetched
  1457.                     Some(Ok(jib_details)) => {
  1458.                         // Define the table data structure
  1459.                         let dataJibsDetails = TableData {
  1460.                             // Table headers
  1461.                             headers: vec![
  1462.                                 view! { <p class="max-w-300">"Operator"</p> }.into_view(),
  1463.                                 view! { <p>"Payment" <br/> "Date"</p> }.into_view(),
  1464.                                 view! { <p class="max-w-200">"Reference Number"</p> }.into_view(),
  1465.                                 view! { <p>"Cost Center"</p> }.into_view(),
  1466.                                 view! { <p>"Venture"<br />"Number"</p> }.into_view(),
  1467.                                 view! { <p>"Description"</p> }.into_view(),
  1468.                                 view! { <p>"Amount"</p> }.into_view(),
  1469.                             ],
  1470.                             // Table rows mapped from the fetched jib details
  1471.                             rows: jib_details.iter().map(|jib_detail| {
  1472.                                 vec![
  1473.                                     view! { <p>{jib_detail.payor.clone()}</p> }.into_view(),
  1474.                                     view! { <p>{jib_detail.payment_date.clone()}</p> }.into_view(),
  1475.                                     view! { <p class="max-w-200">{jib_detail.invoice_number.clone()}</p> }.into_view(),
  1476.                                     view! { <p>{jib_detail.cost_center.clone()}</p> }.into_view(),
  1477.                                     view! { <p>{jib_detail.venture_number.clone()}</p> }.into_view(),
  1478.                                     view! { <p>{jib_detail.description.clone()}</p> }.into_view(),
  1479.                                     view! { <p>{jib_detail.total_amount.clone()}</p> }.into_view()
  1480.                                 ]
  1481.                             }).collect(),
  1482.                             links: vec![Some(vec!["https://www.google.com".to_string(); 4])],
  1483.                             has_totals: false,
  1484.                         };
  1485.                         // Render the table with the provided data
  1486.                         view! {
  1487.                             <div>
  1488.                                 <Table data={dataJibsDetails} />
  1489.                             </div>
  1490.                         }
  1491.                     },
  1492.                     // If an error occurs while fetching data
  1493.                     Some(Err(_)) => {
  1494.                         log::error!("Error fetching jib details {}", jib_details_resource.revenue_rows.get().unwrap().err().unwrap());
  1495.                         view! { <div><p>"Error..."</p></div> }
  1496.                     },
  1497.                     // If no data is available (still loading)
  1498.                     None => view! {
  1499.                         <div>
  1500.                             <TableSkeleton />
  1501.                         </div>
  1502.                     },
  1503.                 }
  1504.             }
  1505.         </Suspense>
  1506.  
  1507.  
  1508.         <h2 class="title-guardian-footer">Revenue and JIB Summary</h2>
  1509.         <p class="font-georgia mb-0">Please see all your Revenue and JIBs listed here.</p>
  1510.  
  1511.         <Suspense fallback={move || view!
  1512.             {
  1513.                 <div>
  1514.                     <TableSkeleton />
  1515.                 </div>
  1516.             }
  1517.         }>
  1518.             {move ||
  1519.                 // Check the result of fetching revenue and JIB summary data
  1520.                 match jib_rev_jib_summary.revenue_rows.get() {
  1521.                     // If revenue and JIB summary data is successfully fetched
  1522.                     Some(Ok(rev_jib_summary)) => {
  1523.                         // Define the table data structure
  1524.                         let dataRevenueAndJibsSummary = TableData {
  1525.                             // Table headers
  1526.                             headers: vec![
  1527.                                 view! { <p class="max-w-300">"Operator"</p> }.into_view(),
  1528.                                 view! { <p>"Net" <br/> "Revenue"</p> }.into_view(),
  1529.                                 view! { <p>"Jib Amount"</p> }.into_view(),
  1530.                                 view! { <p>"Year"</p> }.into_view(),
  1531.                             ],
  1532.                             // Table rows mapped from the fetched revenue and JIB summary
  1533.                             rows: rev_jib_summary.iter().map(|rev_jib_summary| {
  1534.                                 vec![
  1535.                                     view! { <p class="max-w-300">{rev_jib_summary.operator_name.clone()}</p> }.into_view(),
  1536.                                     view! { <p>{rev_jib_summary.total_share_net_revenue.clone()}</p> }.into_view(),
  1537.                                     view! { <p>{rev_jib_summary.total_jib_amount.clone()}</p> }.into_view(),
  1538.                                     view! { <p>{rev_jib_summary.year.clone()}</p> }.into_view(),
  1539.                                 ]
  1540.                             }).collect(),
  1541.                             links: vec![Some(vec!["https://www.google.com".to_string(); 4])],
  1542.                             has_totals: false,
  1543.                         };
  1544.                         // Render the table with the provided data
  1545.                         view! {
  1546.                             <div>
  1547.                                 <Table data={dataRevenueAndJibsSummary} />
  1548.                             </div>
  1549.                         }
  1550.                     },
  1551.                     // If an error occurs while fetching data
  1552.                     Some(Err(_)) => {
  1553.                         log::error!("Error fetching revenue and JIB summary {}", jib_rev_jib_summary.revenue_rows.get().unwrap().err().unwrap());
  1554.                         view! { <div><p>"Error..."</p></div> }
  1555.                     },
  1556.                     // If no data is available (still loading)
  1557.                     None => view! {
  1558.                         <div>
  1559.                             <TableSkeleton />
  1560.                         </div>
  1561.                     },
  1562.                 }
  1563.             }
  1564.         </Suspense>
  1565.  
  1566.         <h2 class="title-guardian-footer">Revenue and JIB Details</h2>
  1567.         <p class="font-georgia">Please see all your Revenue and JIB details by well listed here.</p>
  1568.  
  1569.         <Suspense fallback={move || view!
  1570.             {
  1571.                 <div>
  1572.                     <TableSkeleton />
  1573.                 </div>
  1574.             }
  1575.         }>
  1576.             {move ||
  1577.                     // Check the result of fetching revenue and JIB details data
  1578.                     match jib_rev_jib_details.revenue_rows.get() {
  1579.                         // If revenue and JIB details data is successfully fetched
  1580.                         Some(Ok(rev_jib_details)) => {
  1581.                             // Define the table data structure
  1582.                             let dataRevenueAndJibsDetails = TableData {
  1583.                                 // Table headers
  1584.                                 headers: vec![
  1585.                                     view! { <p>"Well"</p> }.into_view(),
  1586.                                     view! { <p>"Share Revenue"</p> }.into_view(),
  1587.                                     view! { <p>"Share Taxes"</p> }.into_view(),
  1588.                                     view! { <p>"Share Deductions"</p> }.into_view(),
  1589.                                     view! { <p>"Net" <br/> "Revenue"</p> }.into_view(),
  1590.                                     view! { <p>"JIB Amount"</p> }.into_view(),
  1591.                                     view! { <p>"Year"</p> }.into_view(),
  1592.                                 ],
  1593.                                 // Table rows mapped from the fetched revenue and JIB details
  1594.                                 rows: rev_jib_details.iter().map(|rev_jib_detail| {
  1595.                                     vec![
  1596.                                         view! { <p>{rev_jib_detail.well_name.clone()}</p> }.into_view(),
  1597.                                         view! { <p>{rev_jib_detail.total_share_gross_revenue.clone()}</p> }.into_view(),
  1598.                                         view! { <p>{rev_jib_detail.total_share_taxes.clone()}</p> }.into_view(),
  1599.                                         view! { <p>{rev_jib_detail.total_share_deductions.clone()}</p> }.into_view(),
  1600.                                         view! { <p>{rev_jib_detail.total_share_net_revenue.clone()}</p> }.into_view(),
  1601.                                         view! { <p>{rev_jib_detail.total_jib_amount.clone()}</p> }.into_view(),
  1602.                                         view! { <p>{rev_jib_detail.year.clone()}</p> }.into_view(),
  1603.                                     ]
  1604.                                 }).collect(),
  1605.                                 links: vec![Some(vec!["https://www.google.com".to_string(); 4])],
  1606.                                 has_totals: false,
  1607.                         };
  1608.                         // Render the table with the provided data
  1609.                         view! {
  1610.                             <div>
  1611.                                 <Table data={dataRevenueAndJibsDetails} />
  1612.                             </div>
  1613.                         }
  1614.                     },
  1615.                     // If an error occurs while fetching data
  1616.                     Some(Err(_)) => {
  1617.                         log::error!("Error fetching revenue and JIB details {}", jib_rev_jib_details.revenue_rows.get().unwrap().err().unwrap());
  1618.                         view! { <div><p>"Error..."</p></div> }
  1619.                     },
  1620.                     // If no data is available (still loading)
  1621.                     None => view! {
  1622.                         <div>
  1623.                             <TableSkeleton />
  1624.                         </div>
  1625.                     },
  1626.                 }
  1627.             }
  1628.         </Suspense>
  1629.       </div>
  1630.     }
  1631. }
  1632.  
  1633. ================
  1634. File: gmm_client/src/pages/leases.rs
  1635. ================
  1636. use leptos::*;
  1637. use crate::{components::table::*, tables::leases::resource::LeasesResource};
  1638. use crate::components::table_skeleton::TableSkeleton; // Import the TableSkeleton component
  1639.  
  1640. #[component]
  1641. pub fn Leases() -> impl IntoView {
  1642.     let leases_resource = LeasesResource::new();
  1643.  
  1644.     view! {
  1645.       <div class="tables">
  1646.         <h2 class="title-guardian-content">Leases</h2>
  1647.         <p class="font-georgia mb-0">A current listing of your owned leases.</p>
  1648.  
  1649.         <Suspense fallback={move || view!
  1650.               {
  1651.                   <div>
  1652.                       <TableSkeleton />
  1653.                   </div>
  1654.               }
  1655.             }>
  1656.                 {move ||
  1657.                     // Check the result of fetching leases data
  1658.                     match leases_resource.revenue_rows.get() {
  1659.                         // If leases data is successfully fetched
  1660.                         Some(Ok(lease)) => {
  1661.                             // Define the table data structure
  1662.                             let dataLeases = TableData {
  1663.                                 // Table headers
  1664.                                 headers: vec![
  1665.                                     view! { <p class="max-w-400">"Lessee"</p> }.into_view(),
  1666.                                     view! { <p>"Effective"</p> }.into_view(),
  1667.                                     view! { <p>"Expiration"</p> }.into_view(),
  1668.                                     view! { <p>"Term"</p> }.into_view(),
  1669.                                     view! { <p>"Royalty"</p> }.into_view(),
  1670.                                     view! { <p>"Lease Type"</p> }.into_view(),
  1671.                                     view! { <p>"Status"</p> }.into_view(),
  1672.                                 ],
  1673.                                 // Table rows mapped from the fetched leases
  1674.                                 rows: lease.iter().map(|lease| {
  1675.                                     vec![
  1676.                                         view! { <p class="max-w-400">{lease.lessee.clone()}</p> }.into_view(),
  1677.                                         view! { <p>{lease.effective.clone()}</p> }.into_view(),
  1678.                                         view! { <p>{lease.expiration.clone()}</p> }.into_view(),
  1679.                                         view! { <p>{lease.term.clone()}</p> }.into_view(),
  1680.                                         view! { <p>{lease.royalty.clone()}</p> }.into_view(),
  1681.                                         view! { <p>{lease.lease_type.clone()}</p> }.into_view(),
  1682.                                         view! { <p>{lease.status.clone()}</p> }.into_view(),
  1683.                                     ]
  1684.                                 }).collect::<Vec<_>>(),
  1685.                                 links: vec![Some(vec!["https://www.google.com".to_string(); 4])],
  1686.                                 has_totals: false,
  1687.                             };
  1688.                             // Render the table with the provided data
  1689.                             view! {
  1690.                                 <div>
  1691.                                     <Table data={dataLeases} />
  1692.                                 </div>
  1693.                             }
  1694.                         },
  1695.                         // If an error occurs while fetching data
  1696.                         Some(Err(_)) => {
  1697.                             log::error!("Error fetching leases {}", leases_resource.revenue_rows.get().unwrap().err().unwrap());
  1698.                             view! { <div><p>"Error..."</p></div> }
  1699.                         },
  1700.                         // If no data is available (still loading)
  1701.                         None => view! {
  1702.                             <div>
  1703.                                 <TableSkeleton />
  1704.                             </div>
  1705.                         },
  1706.                     }
  1707.                 }
  1708.             </Suspense>
  1709.       </div>
  1710.     }
  1711. }
  1712.  
  1713. ================
  1714. File: gmm_client/src/pages/stats.rs
  1715. ================
  1716. use crate::components::line_chart::*;
  1717. use crate::components::table::*;
  1718. use crate::components::table_skeleton::TableSkeleton;
  1719. use crate::tables::statslistofcounts::resource::StatsListOfCountsResource;
  1720. use crate::tables::statsproduction::resource::StatsProductionResource;
  1721. use crate::tables::statstopoperators::resource::StatsTopOperatorsResource;
  1722. use leptos::*;
  1723.  
  1724. #[component]
  1725. pub fn Stats() -> impl IntoView {
  1726.     let stats_production_resource = StatsProductionResource::new();
  1727.     let stats_top_operators_resource = StatsTopOperatorsResource::new();
  1728.     let stats_list_of_counts_resource = StatsListOfCountsResource::new();
  1729.  
  1730.     view! {
  1731.       <div class="tables">
  1732.         <h2 class="title-guardian-content">Stats</h2>
  1733.         <p class="font-georgia">These are your top operators for the month of <strong>2024-04.</strong></p>
  1734.         <p class="font-georgia mb-0">The Exponential Mean is the average revenue on a log scale and scatter is how dispersed the revenue payment amounts are for each operator.</p>
  1735.  
  1736.         <Suspense fallback={move || view!
  1737.           {
  1738.               <div>
  1739.                   <TableSkeleton />
  1740.               </div>
  1741.           }
  1742.         }>
  1743.             {move ||
  1744.                 // Check the result of fetching top operators data
  1745.                 match stats_top_operators_resource.top_operators.get() {
  1746.                     // If top operators data is successfully fetched
  1747.                     Some(Ok(operator)) => {
  1748.                         // Define the table data structure
  1749.                         let dataTopOperators = TableData {
  1750.                             // Table headers
  1751.                             headers: vec![
  1752.                                 view! { <p class="min-w-200">"Operator"</p> }.into_view(),
  1753.                                 view! { <p>"Owner Net Revenue"</p> }.into_view(),
  1754.                                 view! { <p>"Exponential Mean"</p> }.into_view(),
  1755.                                 view! { <p>"Scatter"</p> }.into_view(),
  1756.                             ],
  1757.                             // Table rows mapped from the fetched top operators data
  1758.                             rows: operator.iter().map(|operator| {
  1759.                                 vec![
  1760.                                     view! { <p>{operator.operator_purchaser.clone()}</p> }.into_view(),
  1761.                                     view! { <p>{operator.owner_net_revenue.clone()}</p> }.into_view(),
  1762.                                     view! { <p>{operator.exponential_mean.clone()}</p> }.into_view(),
  1763.                                     view! { <p>{operator.scatter.clone()}</p> }.into_view(),
  1764.                                 ]
  1765.                             }).collect(),
  1766.                             links: vec![Some(vec!["https://www.google.com".to_string(); 4])],
  1767.                             has_totals: false,
  1768.                         };
  1769.                         // Render the table with the provided data
  1770.                         view! {
  1771.                             <div>
  1772.                                 <Table data={dataTopOperators} />
  1773.                             </div>
  1774.                         }
  1775.                     },
  1776.                     // If an error occurs while fetching data
  1777.                     Some(Err(_)) => {
  1778.                         log::error!("Error fetching leases {}", stats_top_operators_resource.top_operators.get().unwrap().err().unwrap());
  1779.                         view! { <div><p>"Error..."</p></div> }
  1780.                     },
  1781.                     // If the data is still loading
  1782.                     None => {
  1783.                         view! {
  1784.                           <div>
  1785.                             <TableSkeleton />
  1786.                         </div>
  1787.                         }
  1788.                     }
  1789.                 } }
  1790.         </Suspense>
  1791.  
  1792.         <h2 class="title-guardian-footer">Summary List of Counts</h2>
  1793.  
  1794.         <Suspense fallback={move || view!
  1795.             {
  1796.               <div class="w-176 h-126 skeleton" />
  1797.             }
  1798.           }>
  1799.           {move ||
  1800.             // Check the result of fetching summary list of counts data
  1801.             match stats_list_of_counts_resource.stats_rows.get() {
  1802.                 // If summary list of counts data is successfully fetched
  1803.                 Some(Ok(counts)) => {
  1804.                     view! {
  1805.                           <div>
  1806.                             <table class="table-contacts">
  1807.                               {
  1808.                                 counts.iter().map(|count| {
  1809.                                     view! {
  1810.                                       <tr>
  1811.                                         <td class="font-georgia"><p>"Number of States"</p></td>
  1812.                                         <td class="font-georgia text-right"><p>{count.number_of_states.clone()}</p></td>
  1813.                                       </tr>
  1814.                                       <tr>
  1815.                                         <td class="font-georgia"><p>"Number of Counties"</p></td>
  1816.                                         <td class="font-georgia text-right"><p>{count.number_of_counties.clone()}</p></td>
  1817.                                       </tr>
  1818.                                       <tr>
  1819.                                         <td class="font-georgia"><p>"Number of Assets"</p></td>
  1820.                                         <td class="font-georgia text-right"><p>{count.number_of_assets.clone()}</p></td>
  1821.                                       </tr>
  1822.                                       <tr>
  1823.                                         <td class="font-georgia"><p>"Number of Leases"</p></td>
  1824.                                         <td class="font-georgia text-right"><p>{count.number_of_leases.clone()}</p></td>
  1825.                                       </tr>
  1826.                                       <tr>
  1827.                                         <td class="font-georgia"><p>"Number of Wells"</p></td>
  1828.                                         <td class="font-georgia text-right"><p>{count.number_of_wells.clone()}</p></td>
  1829.                                       </tr>
  1830.                                     }
  1831.                                 }).collect::<Vec<_>>()
  1832.                               }
  1833.                             </table>
  1834.                           </div>
  1835.                         }
  1836.                 },
  1837.                 // If an error occurs while fetching data
  1838.                 Some(Err(_)) => {
  1839.                     log::error!("Error fetching leases {}", stats_list_of_counts_resource.stats_rows.get().unwrap().err().unwrap());
  1840.                     view! { <div><p>"Error..."</p></div> }
  1841.                 },
  1842.                 // If no data is available (still loading)
  1843.                 None => view! {
  1844.                     <div>
  1845.                     </div>
  1846.                 },
  1847.             } }
  1848.         </Suspense>
  1849.  
  1850.         <h2 class="title-guardian-footer">Spot Prices</h2>
  1851.  
  1852.         <div class="d-flex flex-column justify-content-center align-items-center gap-2">
  1853.           <LineChart
  1854.             title="Europe Brent FOB Price Trend — USD per barrel".to_string()
  1855.             image_url="/europe.png".to_string()
  1856.           />
  1857.  
  1858.           <LineChart
  1859.             title="Henry Hub Natural Gas FOB Price Trend — USD per million BTU".to_string()
  1860.             image_url="/henry.png".to_string()
  1861.           />
  1862.  
  1863.           <LineChart
  1864.             title="WTI Cushing OK FOB Price Trend — USD per barrel".to_string()
  1865.             image_url="/wti.png".to_string()
  1866.           />
  1867.  
  1868.           <LineChart
  1869.             title="U.S. Natural Gas Liquid Composite FOB Price Trend — USD per million BTU".to_string()
  1870.             image_url="/us.png".to_string()
  1871.           />
  1872.         </div>
  1873.  
  1874.         <h2 class="mt-5 title-guardian-footer">Production Statistics</h2>
  1875.         <p class="font-georgia">This table presents production statistics on the period from November 1st, 2019 through the end of the current reporting month.</p>
  1876.  
  1877.         <Suspense fallback={move || view!
  1878.           {
  1879.               <div>
  1880.                   <TableSkeleton />
  1881.               </div>
  1882.           }
  1883.         }>
  1884.             {move ||
  1885.                 // Check the result of fetching stats production data
  1886.                 match stats_production_resource.stats_rows.get() {
  1887.                     // If stats production data is successfully fetched
  1888.                     Some(Ok(stats)) => {
  1889.                         // Define the table data structure
  1890.                         let dataStatsProduction = TableData {
  1891.                             // Table headers
  1892.                             headers: vec![
  1893.                                 view! { <p>"Product"</p> }.into_view(),
  1894.                                 view! { <p>"Ave Price"<br />"Min Price"<br />"Max Price"<br />"Volatility"</p> }.into_view(),
  1895.                                 view! { <p>"Ave Prod Rate *"<br />"Min Prod Rate *"<br />"Max Prod Rate *"<br />"Volatility"</p> }.into_view(),
  1896.                                 view! { <p>"Gross"<br />"Ave Rate *"</p> }.into_view(),
  1897.                             ],
  1898.                             // Table rows mapped from the fetched stats production data
  1899.                             rows: stats.iter().map(|stat| {
  1900.                                 vec![
  1901.                                     view! { <p>{stat.product.clone()}</p> }.into_view(),
  1902.                                     view! { <p>{stat.avg_price.clone()}<br />{stat.min_price.clone()}<br />{stat.max_price.clone()}<br />{stat.price_volatility.clone()}</p> }.into_view(),
  1903.                                     view! { <p>{stat.avg_prod_rate.clone()}<br />{stat.min_prod_rate.clone()}<br />{stat.max_prod_rate.clone()}<br />{stat.prod_volatility.clone()}</p> }.into_view(),
  1904.                                     view! { <p>{stat.gross_avg_rate.clone()}<br />{stat.avg_prod_rate.clone()}</p> }.into_view(),
  1905.                                 ]
  1906.                             }).collect(),
  1907.                             links: vec![Some(vec!["https://www.google.com".to_string(); 4])],
  1908.                             has_totals: false,
  1909.                         };
  1910.                         // Render the table with the provided data
  1911.                         view! {
  1912.                             <div>
  1913.                                 <Table data={dataStatsProduction} />
  1914.                             </div>
  1915.                         }
  1916.                     },
  1917.                     // If an error occurs while fetching data
  1918.                     Some(Err(_)) => {
  1919.                         log::error!("Error fetching leases {}", stats_production_resource.stats_rows.get().unwrap().err().unwrap());
  1920.                         view! { <div><p>"Error..."</p></div> }
  1921.                     },
  1922.                     // If the data is still loading
  1923.                     None => {
  1924.                         view! {
  1925.                           <div>
  1926.                             <TableSkeleton />
  1927.                         </div>
  1928.                         }
  1929.                     }
  1930.                 } }
  1931.         </Suspense>
  1932.  
  1933.         <p class="font-georgia">* The bottom two statistics are presented as average daily production mil rates rather than the more common month s production value. The units are thousandths of units of production per day and thousandths of U.S. dollars per day respectively. As months lengths may vary, changes over time may more accurately be compared using the daily production rate as the production metric. The gross average rate in the fourth column is an indicator of the rate at which you acquire gross revenue. It is your share of the income per day, calculated by multiplying price, volume per day times, and the mil factor of 1,000.</p>
  1934.         <p class="font-georgia">The abbreviations "ave", "min", and "max" are average (mean), minimum, and maximum over the course of the reporting period.</p>
  1935.         <p class="font-georgia">Volatility, the bottom most statistic in each row, has been evaluated relative to price. This practice is called normalization, allowing volatility to be rationally compared between energy products. Volatility is shown as the quotient of the standard deviation over the mean. Although some reporting products do not divide by the mean, such would be a conceptual error for a table like this one. The units of a standard deviation are the same as that of the mean, so the quotient is unitless. Comparison of volatility requires the value to be unitless so that it is free from physical unit designations, which vary in economic meaning from product to product.</p>
  1936.  
  1937.       </div>
  1938.     }
  1939. }
  1940.  
  1941. ================
  1942. File: gmm_client/src/pages/tax_year.rs
  1943. ================
  1944. use leptos::*;
  1945. use crate::components::table::*;
  1946. use crate::components::table_skeleton::TableSkeleton;
  1947.  
  1948. use crate::tables::taxyearfullyeartotals::resource::TaxYearFullYearTotalsResource;
  1949. use crate::tables::taxyearinterestbystate::resource::TaxYearInterestByStateResource;
  1950. use crate::tables::taxyearrevenueand1099s::resource::TaxYearRevenueAnd1099sResource;
  1951. use crate::tables::taxyearwellsbystate::resource::TaxYearWellsByStateResource;
  1952. use crate::tables::taxyear1099details::resource::TaxYear1099DetailsResource;
  1953.  
  1954. #[component]
  1955. pub fn TaxYear() -> impl IntoView {
  1956.   let tax_year_1099_details_resource = TaxYear1099DetailsResource::new();
  1957.   let tax_year_full_year_totals_resource = TaxYearFullYearTotalsResource::new();
  1958.   let tax_year_interest_by_state_resource = TaxYearInterestByStateResource::new();
  1959.   let tax_year_revenue_and_1099s_resource = TaxYearRevenueAnd1099sResource::new();
  1960.   let tax_year_wells_by_state_resource = TaxYearWellsByStateResource::new();
  1961.  
  1962.     view! {
  1963.       <div class="tables">
  1964.         <h2 class="title-guardian-content">Tax Year</h2>
  1965.  
  1966.         <h2 class="title-guardian-footer">Your 2024 Full Year Totals</h2>
  1967.           <Suspense fallback={move || view!
  1968.             {
  1969.               <div class="w-176 h-126 skeleton" />
  1970.             }
  1971.           }>
  1972.           {
  1973.             move ||
  1974.               match tax_year_full_year_totals_resource.totals_rows.get() {
  1975.                 Some(Ok(data)) => {
  1976.                   view! {
  1977.                     <div>
  1978.                       <table class="table-contacts">
  1979.                         {
  1980.                           data.into_iter().map(|row| view! {
  1981.                             <tr>
  1982.                               <td class="font-georgia"><p>"Gross Revenue"</p></td>
  1983.                               <td class="font-georgia text-right"><p>{row.gross_share}</p></td>
  1984.                             </tr>
  1985.                             <tr>
  1986.                               <td class="font-georgia"><p>"Share Taxes"</p></td>
  1987.                               <td class="font-georgia text-right"><p>{row.share_taxes}</p></td>
  1988.                             </tr>
  1989.                             <tr>
  1990.                               <td class="font-georgia"><p>"Share Deductions"</p></td>
  1991.                               <td class="font-georgia text-right"><p>{row.share_deductions}</p></td>
  1992.                             </tr>
  1993.                             <tr>
  1994.                               <td class="font-georgia"><p>"Net" <br/> "Revenue"</p></td>
  1995.                               <td class="font-georgia text-right"><p>{row.net_revenue}</p></td>
  1996.                             </tr>
  1997.                             <tr>
  1998.                               <td class="font-georgia"><p>"JIBs"</p></td>
  1999.                               <td class="font-georgia text-right"><p>{row.jibs}</p></td>
  2000.                             </tr>
  2001.                           }).collect_view()
  2002.                         }
  2003.                       </table>
  2004.                     </div>
  2005.                   }
  2006.                 },
  2007.                 Some(Err(_)) => {
  2008.                   view! { <div><p>"Error loading data"</p></div> }
  2009.                 },
  2010.                 None => {
  2011.                   view! { <div><p>"Loading data..."</p></div> }
  2012.                 }
  2013.               }
  2014.           }
  2015.         </Suspense>
  2016.  
  2017.         <h2 class="title-guardian-footer">Wells by State for the year 2024</h2>
  2018.  
  2019.         <Suspense fallback={move || view!
  2020.             {
  2021.                 <div>
  2022.                     <TableSkeleton />
  2023.                 </div>
  2024.             }
  2025.         }>
  2026.           {
  2027.             move || {
  2028.               match tax_year_wells_by_state_resource.rows.get() {
  2029.                   Some(Ok(data)) => {
  2030.                       let data_table = TableData {
  2031.                         headers: vec![
  2032.                             view! { <p>"State"</p> }.into_view(),
  2033.                             view! { <p>"Gross"<br />"Revenue"</p> }.into_view(),
  2034.                             view! { <p>"Taxes"</p> }.into_view(),
  2035.                             view! { <p>"Deductions"</p> }.into_view(),
  2036.                             view! { <p>"Net" <br/> "Revenue"</p> }.into_view(),
  2037.                             view! { <p>"Percentage of Portfolio"</p> }.into_view(),
  2038.                         ],
  2039.                         rows: data.iter().map(|row| {
  2040.                             vec![
  2041.                                 view! { <p>{row.state.clone()}</p> }.into_view(),
  2042.                                 view! { <p>{row.gross_revenue.clone()}</p> }.into_view(),
  2043.                                 view! { <p>{row.taxes.clone()}</p> }.into_view(),
  2044.                                 view! { <p>{row.deductions.clone()}</p> }.into_view(),
  2045.                                 view! { <p>{row.net_revenue.clone()}</p> }.into_view(),
  2046.                                 view! { <p>{row.percentage_of_portfolio.clone()}</p> }.into_view(),
  2047.                             ]
  2048.                         }).collect(),
  2049.                         links: vec![None],
  2050.                         has_totals: false,
  2051.                       };
  2052.                       view! {
  2053.                         <div>
  2054.                           <Table
  2055.                             data={data_table}
  2056.                           />
  2057.                         </div>
  2058.                       }
  2059.                   },
  2060.                   Some(Err(_)) => {
  2061.                       view! {
  2062.                           <div>
  2063.                               <p>"Error loading data"</p>
  2064.                           </div>
  2065.                       }
  2066.                   },
  2067.                   None => {
  2068.                       view! {
  2069.                           <div>
  2070.                               <p>"Loading data..."</p>
  2071.                           </div>
  2072.                       }
  2073.                   }
  2074.               }
  2075.             }
  2076.           }
  2077.         </Suspense>
  2078.  
  2079.         // <Table data={dataWell} />
  2080.  
  2081.         <h2 class="title-guardian-footer">Interest by State for the year 2024</h2>
  2082.  
  2083.         <Suspense fallback={move || view!
  2084.             {
  2085.                 <div>
  2086.                     <TableSkeleton />
  2087.                 </div>
  2088.             }
  2089.         }>
  2090.           {
  2091.             move || {
  2092.               match tax_year_interest_by_state_resource.state_rows.get() {
  2093.                   Some(Ok(data)) => {
  2094.                       let data_table = TableData {
  2095.                         headers: vec![
  2096.                             view! { <p>"State"</p> }.into_view(),
  2097.                             view! { <p>"Gross"<br />"Revenue"</p> }.into_view(),
  2098.                             view! { <p>"Taxes"</p> }.into_view(),
  2099.                             view! { <p>"Deductions"</p> }.into_view(),
  2100.                             view! { <p>"Net" <br/> "Revenue"</p> }.into_view(),
  2101.                             view! { <p>"Percentage of Portfolio"</p> }.into_view(),
  2102.                         ],
  2103.                         rows: data.iter().map(|row| {
  2104.                             vec![
  2105.                                 view! { <p>{row.state.clone()}</p> }.into_view(),
  2106.                                 view! { <p>{row.gross_revenue.clone()}</p> }.into_view(),
  2107.                                 view! { <p>{row.taxes.clone()}</p> }.into_view(),
  2108.                                 view! { <p>{row.deductions.clone()}</p> }.into_view(),
  2109.                                 view! { <p>{row.net_revenue.clone()}</p> }.into_view(),
  2110.                                 view! { <p>{row.interest_type.clone()}</p> }.into_view(),
  2111.                             ]
  2112.                         }).collect(),
  2113.                         links: vec![None],
  2114.                         has_totals: false,
  2115.                       };
  2116.                       view! {
  2117.                         <div>
  2118.                           <Table
  2119.                             data={data_table}
  2120.                           />
  2121.                         </div>
  2122.                       }
  2123.                   },
  2124.                   Some(Err(_)) => {
  2125.                       view! {
  2126.                           <div>
  2127.                               <p>"Error loading data"</p>
  2128.                           </div>
  2129.                       }
  2130.                   },
  2131.                   None => {
  2132.                       view! {
  2133.                           <div>
  2134.                               <p>"Loading data..."</p>
  2135.                           </div>
  2136.                       }
  2137.                   }
  2138.               }
  2139.             }
  2140.           }
  2141.         </Suspense>
  2142.        
  2143.         // <Table data={dataInterest} />
  2144.  
  2145.  
  2146.  
  2147.         <h2 class="title-guardian-footer">1099 Details</h2>
  2148.         <p class="font-georgia mb-0">These amounts are based on operator (payor) reporting through 2024-03-01.</p>
  2149.  
  2150.         <Suspense fallback={move || view!
  2151.             {
  2152.                 <div>
  2153.                     <TableSkeleton />
  2154.                 </div>
  2155.             }
  2156.         }>
  2157.           {
  2158.             move || {
  2159.               match tax_year_1099_details_resource.details_rows.get() {
  2160.                   Some(Ok(data)) => {
  2161.                       let data_table = TableData {
  2162.                         headers: vec![
  2163.                             view! { <p>"Payer"</p> }.into_view(),
  2164.                             view! { <p>"TIN"</p> }.into_view(),
  2165.                             view! { <p>"Box #"</p> }.into_view(),
  2166.                             view! { <p>"Box Name"</p> }.into_view(),
  2167.                             view! { <p>"Reported"</p> }.into_view(),
  2168.                         ],
  2169.                         rows: data.iter().map(|row| {
  2170.                             vec![
  2171.                                 view! { <p>{row.payee.clone()}</p> }.into_view(),
  2172.                                 view! { <p>{row.tin.clone()}</p> }.into_view(),
  2173.                                 view! { <p>{row.box_number.clone()}</p> }.into_view(),
  2174.                                 view! { <p>{row.box_name.clone()}</p> }.into_view(),
  2175.                                 view! { <p>{row.reported_amount.clone()}</p> }.into_view(),
  2176.                             ]
  2177.                         }).collect(),
  2178.                         links: vec![None],
  2179.                         has_totals: false,
  2180.                       };
  2181.                       view! {
  2182.                         <div>
  2183.                           <Table
  2184.                             data={data_table}
  2185.                           />
  2186.                         </div>
  2187.                       }
  2188.                   },
  2189.                   Some(Err(_)) => {
  2190.                       view! {
  2191.                           <div>
  2192.                               <p>"Error loading data"</p>
  2193.                           </div>
  2194.                       }
  2195.                   },
  2196.                   None => {
  2197.                       view! {
  2198.                           <div>
  2199.                               <p>"Loading data..."</p>
  2200.                           </div>
  2201.                       }
  2202.                   }
  2203.               }
  2204.             }
  2205.           }
  2206.         </Suspense>
  2207.  
  2208.         // <Table data={data1099} />
  2209.  
  2210.         <h2 class="title-guardian-footer">Revenue and 1099 Totals for the year 2024</h2>
  2211.         <p class="font-georgia mb-0">Operators with revenue under $600 have been marked with an asterisk. IRS Form 1099-MISC does not require reporting of income under $600.</p>
  2212.         <Suspense fallback={move || view!
  2213.             {
  2214.                 <div>
  2215.                     <TableSkeleton />
  2216.                 </div>
  2217.             }
  2218.         }>
  2219.           {
  2220.             move || {
  2221.               match tax_year_revenue_and_1099s_resource.rows.get() {
  2222.                   Some(Ok(data)) => {
  2223.                       let data_table = TableData {
  2224.                         headers: vec![
  2225.                             view! { <p class="min-w-200">"Operator"</p> }.into_view(),
  2226.                             view! { <p>"Gross"<br />"Revenue"</p> }.into_view(),
  2227.                             view! { <p>"Taxes"</p> }.into_view(),
  2228.                             view! { <p>"Deducts"</p> }.into_view(),
  2229.                             view! { <p>"Net"<br />"Revenue"</p> }.into_view(),
  2230.                             view! { <p>"1099"<br />"Amount"</p> }.into_view(),
  2231.                             view! { <p>"Difference"<br />"($)"</p> }.into_view(),
  2232.                             view! { <p>"Difference"<br />"(%)"</p> }.into_view(),
  2233.                             view! { <p>"Material Difference (over"<br />"25%)"</p> }.into_view(),
  2234.                         ],
  2235.                         rows: data.iter().map(|row| {
  2236.                             vec![
  2237.                                 view! { <p>{row.operator.clone()}</p> }.into_view(),
  2238.                                 view! { <p>{row.gross_revenue.clone()}</p> }.into_view(),
  2239.                                 view! { <p>{row.taxes.clone()}</p> }.into_view(),
  2240.                                 view! { <p>{row.deducts.clone()}</p> }.into_view(),
  2241.                                 view! { <p>{row.net_revenue.clone()}</p> }.into_view(),
  2242.                                 view! { <p>{row.amount_1099.clone()}</p> }.into_view(),
  2243.                                 view! { <p>{row.difference_dollars.clone()}</p> }.into_view(),
  2244.                                 view! { <p>{row.difference_percent.clone()}</p> }.into_view(),
  2245.                                 view! { <p>{row.material_difference.clone()}</p> }.into_view(),
  2246.                             ]
  2247.                         }).collect(),
  2248.                         links: vec![None],
  2249.                         has_totals: false,
  2250.                       };
  2251.                       view! {
  2252.                         <div>
  2253.                           <Table
  2254.                             data={data_table}
  2255.                           />
  2256.                         </div>
  2257.                       }
  2258.                   },
  2259.                   Some(Err(_)) => {
  2260.                       view! {
  2261.                           <div>
  2262.                               <p>"Error loading data"</p>
  2263.                           </div>
  2264.                       }
  2265.                   },
  2266.                   None => {
  2267.                       view! {
  2268.                           <div>
  2269.                               <p>"Loading data..."</p>
  2270.                           </div>
  2271.                       }
  2272.                   }
  2273.               }
  2274.             }
  2275.           }
  2276.         </Suspense>
  2277.  
  2278.  
  2279.         // <Table data={dataRevenueAnd1099} />
  2280.  
  2281.         <p class="disclaimer mb-0">
  2282.           The above values are as reported prior to the generation of this view. Discrepancies found after all visualizations through December 2023 are accounted for (with respect to all wells for which your interest is known) will be investigated.
  2283.  
  2284.           Guardian recommends you use the 1099 information as is for your tax filings unless your CPA, licensed accounting firm, or IRS savvy legal professional recommends otherwise.
  2285.  
  2286.           Issues in the 1099 amounts can be resolved when full documentation indicating any inaccuracies becomes available to assemble as a complete set of evidence.
  2287.         </p>
  2288.       </div>
  2289.     }
  2290.   }
  2291.  
  2292. // <Table data={dataRevenueAnd1099} />
  2293.  
  2294. ================
  2295. File: gmm_client/src/pages/well_rev.rs
  2296. ================
  2297. use crate::components::table::*;
  2298. use crate::tables::wellrev::resource::WellRevResource;
  2299. use crate::components::table_skeleton::TableSkeleton; // Import the TableSkeleton component
  2300. use leptos::*;
  2301.  
  2302. #[component]
  2303. pub fn WellRev() -> impl IntoView {
  2304.     let well_rev_resource = WellRevResource::new();
  2305.     // let dataWellRev = TableData {
  2306.     //   headers: vec![
  2307.     //       view! { <p>"Operator"</p> }.into_view(),
  2308.     //       view! { <p>"Well/Property"<br />"Name"</p> }.into_view(),
  2309.     //       view! { <p>"Well Number"</p> }.into_view(),
  2310.     //       view! { <p>"Production"<br />"Date"</p> }.into_view(),
  2311.     //       view! { <p>"Product"</p> }.into_view(),
  2312.     //       view! { <p>"Unit"<br />"Price"</p> }.into_view(),
  2313.     //       view! { <p>"Pie"<br />"Gross"<br />"Volume"</p> }.into_view(),
  2314.     //       view! { <p>"Owner"<br />"Proportion"</p> }.into_view(),
  2315.     //       view! { <p>"Share"<br />"Revenue"</p> }.into_view(),
  2316.     //       view! { <p>"Share"<br />"Taxes"</p> }.into_view(),
  2317.     //       view! { <p>"Share"<br />"Deductions"</p> }.into_view(),
  2318.     //       view! { <p>"Net"<br />"Revenue"</p> }.into_view(),
  2319.     //   ],
  2320.     //   rows: vec![
  2321.     //       vec![
  2322.     //           view! { <p>"Operator 1"</p> }.into_view(),
  2323.     //           view! { <p>"Well 1"</p> }.into_view(),
  2324.     //           view! { <p>"42-485-32001"</p> }.into_view(),
  2325.     //           view! { <p>"2024-04-01"</p> }.into_view(),
  2326.     //           view! { <p>"Oil"</p> }.into_view(),
  2327.     //           view! { <p>"50.00"</p> }.into_view(),
  2328.     //           view! { <p>"1000"</p> }.into_view(),
  2329.     //           view! { <p>"0.50"</p> }.into_view(),
  2330.     //           view! { <p>"500.00"</p> }.into_view(),
  2331.     //           view! { <p>"50.00"</p> }.into_view(),
  2332.     //           view! { <p>"25.00"</p> }.into_view(),
  2333.     //           view! { <p>"425.00"</p> }.into_view(),
  2334.     //       ],
  2335.     //       vec![
  2336.     //           view! { <p>"Totals"</p> }.into_view(),
  2337.     //           view! { <p>"Well 1"</p> }.into_view(),
  2338.     //           view! { <p>"42-485-32001"</p> }.into_view(),
  2339.     //           view! { <p>"2024-04-01"</p> }.into_view(),
  2340.     //           view! { <p>"Oil"</p> }.into_view(),
  2341.     //           view! { <p>"50.00"</p> }.into_view(),
  2342.     //           view! { <p>"1000"</p> }.into_view(),
  2343.     //           view! { <p>"0.50"</p> }.into_view(),
  2344.     //           view! { <p>"500.00"</p> }.into_view(),
  2345.     //           view! { <p>"50.00"</p> }.into_view(),
  2346.     //           view! { <p>"25.00"</p> }.into_view(),
  2347.     //           view! { <p>"425.00"</p> }.into_view(),
  2348.     //       ]
  2349.     //   ],
  2350.     //   links: vec![
  2351.     //     Some(vec!["https://www.google.com".to_string(); 4]);2
  2352.     //   ],
  2353.     //   has_totals: true
  2354.     // };
  2355.  
  2356.     view! {
  2357.       <div class="tables">
  2358.         <h2 class="title-guardian-content">Well Revenue (US$)</h2>
  2359.         <p class="font-georgia mb-0">A current listing of your wells for the month of <strong>2024-04.</strong></p>
  2360.  
  2361.  
  2362.         <Suspense fallback={move || view! {
  2363.           <div>
  2364.             <TableSkeleton />
  2365.           </div>
  2366.         }}>
  2367.           {move ||
  2368.             // Check the result of fetching well operations data
  2369.             match well_rev_resource.rows.get() {
  2370.               // If well operations data is successfully fetched
  2371.               Some(Ok(well_revs)) => {
  2372.                 // Define the table data structure
  2373.                 let dataWellRev = TableData {
  2374.                   // Table headers
  2375.                   headers: vec![
  2376.                     view! { <p class="max-w-200">"Operator"</p> }.into_view(),
  2377.                     view! { <p class="max-w-200">"Well/Property"<br />"Name"</p> }.into_view(),
  2378.                     view! { <p class="max-w-200">"Well Number"</p> }.into_view(),
  2379.                     view! { <p class="max-w-200">"Production"<br />"Date"</p> }.into_view(),
  2380.                     view! { <p class="max-w-200">"Product"</p> }.into_view(),
  2381.                     view! { <p class="max-w-200">"Unit"<br />"Price"</p> }.into_view(),
  2382.                     view! { <p class="max-w-200">"Pie"<br />"Gross"<br />"Volume"</p> }.into_view(),
  2383.                     view! { <p class="max-w-200">"Owner"<br />"Proportion"</p> }.into_view(),
  2384.                     view! { <p class="max-w-200">"Share"<br />"Revenue"</p> }.into_view(),
  2385.                     view! { <p class="max-w-200">"Share"<br />"Taxes"</p> }.into_view(),
  2386.                     view! { <p class="max-w-200">"Share"<br />"Deductions"</p> }.into_view(),
  2387.                     view! { <p class="max-w-200">"Net"<br />"Revenue"</p> }.into_view(),
  2388.                   ],
  2389.                   // Table rows mapped from the fetched well revenue
  2390.                   rows: well_revs.iter().map(|well_rev| {
  2391.                     vec![
  2392.                       view! { <p class="max-w-200">{well_rev.operator.clone()}</p> }.into_view(),
  2393.                       view! { <p class="max-w-200">{well_rev.well_property_name.clone()}</p> }.into_view(),
  2394.                       view! { <p class="max-w-200">{well_rev.well_number.clone()}</p> }.into_view(),
  2395.                       view! { <p class="max-w-200">{well_rev.production_date.clone()}</p> }.into_view(),
  2396.                       view! { <p class="max-w-200">{well_rev.product.clone()}</p> }.into_view(),
  2397.                       view! { <p class="max-w-200">{well_rev.unit_price.clone()}</p> }.into_view(),
  2398.                       view! { <p class="max-w-200">{well_rev.pie_gross_volume.clone()}</p> }.into_view(),
  2399.                       view! { <p class="max-w-200">{well_rev.owner_proportion.clone()}</p> }.into_view(),
  2400.                       view! { <p class="max-w-200">{well_rev.share_revenue.clone()}</p> }.into_view(),
  2401.                       view! { <p class="max-w-200">{well_rev.share_taxes.clone()}</p> }.into_view(),
  2402.                       view! { <p class="max-w-200">{well_rev.share_deductions.clone()}</p> }.into_view(),
  2403.                       view! { <p class="max-w-200">{well_rev.net_revenue.clone()}</p> }.into_view(),
  2404.                     ]
  2405.                   }).collect::<Vec<_>>(),
  2406.                   links: vec![Some(vec!["https://www.google.com".to_string(); 4])],
  2407.                   has_totals: false,
  2408.                 };
  2409.                 // Render the table with the provided data
  2410.                 view! {
  2411.                   <div>
  2412.                     <Table data={dataWellRev} />
  2413.                   </div>
  2414.                 }
  2415.               },
  2416.               // If an error occurs while fetching data
  2417.               Some(Err(_)) => {
  2418.                 // Handle error case (e.g., show an error message)
  2419.                 view! {
  2420.                   <div class="error-message">
  2421.                     "Error fetching well rev data."
  2422.                   </div>
  2423.                 }
  2424.               },
  2425.               None => {
  2426.                 // Loading state or initial state before data is fetched
  2427.                 view! {
  2428.                   <div class="loading-message">
  2429.                     "Loading..."
  2430.                   </div>
  2431.                 }
  2432.               },
  2433.             }
  2434.           }
  2435.         </Suspense>
  2436.       </div>
  2437.     }
  2438. }
  2439.  
  2440. ================
  2441. File: gmm_client/src/pages/year_to_date.rs
  2442. ================
  2443. use leptos::*;
  2444. use crate::components::table::*;
  2445. use crate::components::table_skeleton::TableSkeleton;
  2446.  
  2447. use crate::tables::ytdcurrentyear::resource::YTDCurrentYearResource;
  2448. use crate::tables::ytdpasttaxyear::resource::YtdPastTaxYearResource;
  2449. use crate::tables::ytdpfibyoperator::resource::YtdPfiByOperatorResource;
  2450. use crate::tables::ytdpfibyproduct::resource::YtdPfiByProductResource;
  2451. use crate::tables::ytdrevenuebyoperator::resource::YtdRevenueByOperatorResource;
  2452.  
  2453. use crate::tables::ytdcurrentyear::query::YTDCurrentYearRow;
  2454. use crate::tables::ytdpasttaxyear::query::YTDPastTaxYearRow;
  2455. use crate::tables::ytdpfibyoperator::query::YTDPFIByOperatorRow;
  2456. use crate::tables::ytdpfibyproduct::query::YTDPFIByProductRow;
  2457. use crate::tables::ytdrevenuebyoperator::query::YTDRevenueByOperatorRow;
  2458.  
  2459.  
  2460. #[component]
  2461. pub fn YearToDate() -> impl IntoView {
  2462.     // let data = create_data();
  2463.     // let dataYourShare = create_data_your_share();
  2464.     // let dataOperator = create_data_operator();
  2465.     // let dataProjectedFutureIncomeByProduct = create_data_projected_future_income_by_product();
  2466.     // let dataProjectedFutureIncomeByOperator = create_data_projected_future_income_by_operator();
  2467.  
  2468.     let ytd_current_resource = YTDCurrentYearResource::new();
  2469.     let ytd_past_tax_year_resource  = YtdPastTaxYearResource::new();
  2470.     let ytd_pfi_by_operator_resource = YtdPfiByOperatorResource::new();
  2471.     let ytd_pfi_by_product_resource = YtdPfiByProductResource::new();
  2472.     let ytd_revenue_by_operator_resource = YtdRevenueByOperatorResource::new();
  2473.  
  2474.     view! {
  2475.       <div class="tables">
  2476.         <h2 class="title-guardian-content">Year To Date</h2>
  2477.         <p class="font-georgia mb-0">The current year for which Guardian has been provided with reasonably complete information by you, operators, purchasers, government offices, and data aggregators.</p>
  2478.        
  2479.         <Suspense fallback={move || view!
  2480.             {
  2481.                 <div>
  2482.                     <TableSkeleton />
  2483.                 </div>
  2484.             }
  2485.         }>
  2486.             {
  2487.                 move ||
  2488.                 match ytd_current_resource.rows.get() {
  2489.                     Some(Ok(rows)) => {
  2490.                         let dataYtdCurrent = create_ytd_current_data(&rows);
  2491.                         view! {
  2492.                             <div>
  2493.                                 <Table data={dataYtdCurrent} />
  2494.                             </div>
  2495.                         }
  2496.                     },
  2497.                     Some(Err(_)) => {
  2498.                       view! {
  2499.                           <div>
  2500.                               <p>"Error loading data"</p>
  2501.                           </div>
  2502.                       }
  2503.                     },
  2504.                     None => {
  2505.                         view! {
  2506.                             <div>
  2507.                                 <p>"Loading data..."</p>
  2508.                             </div>
  2509.                         }
  2510.                     }
  2511.                 }
  2512.                
  2513.             }
  2514.         </Suspense>
  2515.        
  2516.         <h2 class="title-guardian-content">Your Share for Each Month of 2024</h2>
  2517.         <p class="font-georgia mb-0">These amounts are based on operator reporting for each month of the past tax year.</p>
  2518.        
  2519.         <Suspense fallback={move || view! {
  2520.             <div>
  2521.                 <TableSkeleton />
  2522.             </div>
  2523.         }}>
  2524.             {
  2525.                 move ||
  2526.                 match ytd_past_tax_year_resource.rows.get() {
  2527.                     Some(Ok(rows)) => {
  2528.                         let dataYtdPastTaxYear = create_ytd_past_tax_year_data(&rows);
  2529.                         view! {
  2530.                             <div>
  2531.                                 <Table data={dataYtdPastTaxYear} />
  2532.                             </div>
  2533.                         }
  2534.                     },
  2535.                     Some(Err(_)) => {
  2536.                       view! {
  2537.                           <div>
  2538.                               <p>"Error loading data"</p>
  2539.                           </div>
  2540.                       }
  2541.                     },
  2542.                     None => {
  2543.                         view! {
  2544.                             <div>
  2545.                                 <p>"Loading data..."</p>
  2546.                             </div>
  2547.                         }
  2548.                     }
  2549.                 }
  2550.                
  2551.             }
  2552.         </Suspense>
  2553.  
  2554.         // <Table data={dataYourShare} />
  2555.  
  2556.         <h2 class="title-guardian-content">Revenue by Operator</h2>
  2557.         <p class="font-georgia mb-0">Your revenue to date by operator for the current year.</p>
  2558.  
  2559.         <Suspense fallback={move || view! {
  2560.             <div>
  2561.                 <TableSkeleton />
  2562.             </div>
  2563.         }}>
  2564.             {
  2565.                 move ||
  2566.                 match ytd_revenue_by_operator_resource.rows.get() {
  2567.                     Some(Ok(rows)) => {
  2568.                         let dataYtdRevenueByOperator = create_ytd_revenue_by_operator_data(&rows);
  2569.                         view! {
  2570.                             <div>
  2571.                                 <Table data={dataYtdRevenueByOperator} />
  2572.                             </div>
  2573.                         }
  2574.                     },
  2575.                     Some(Err(_)) => {
  2576.                       view! {
  2577.                           <div>
  2578.                               <p>"Error loading data"</p>
  2579.                           </div>
  2580.                       }
  2581.                     },
  2582.                     None => {
  2583.                         view! {
  2584.                             <div>
  2585.                                 <p>"Loading data..."</p>
  2586.                             </div>
  2587.                         }
  2588.                     }
  2589.                 }
  2590.                
  2591.             }
  2592.         </Suspense>
  2593.  
  2594.         // <Table data={dataOperator} />
  2595.  
  2596.         <h2 class="title-guardian-content">Year To Date</h2>
  2597.         <p class="font-georgia font-bold">
  2598.           The purpose of these tables is to provide a visual representation of the potential cash flow of your asset base at various commodity price ranges. These tables will better assist you in conservatively estimating the potential future gains or losses of your asset base, given the fluctuation in commodity prices. Please note, these tables are used only for projection purposes and are not provided to determine or to predict actual future value. Also, please remember these assets are both depleting and highly subject to operational and geopolitical issues as well as national and global supply chain issues.
  2599.         </p>
  2600.  
  2601.         <h2 class="title-guardian-content">Projected Future Income by Product</h2>
  2602.         <p class="font-georgia mb-0">
  2603.           This is the actual one month revenue average of these commodities for the presented timeframes.
  2604.         </p>
  2605.  
  2606.         <Suspense fallback={move || view! {
  2607.             <div>
  2608.                 <TableSkeleton />
  2609.             </div>
  2610.         }}>
  2611.             {
  2612.                 move ||
  2613.                 match ytd_pfi_by_product_resource.rows.get() {
  2614.                     Some(Ok(rows)) => {
  2615.                         let dataYtdPfiByProduct = create_ytd_pfi_by_product_data(&rows);
  2616.                         view! {
  2617.                             <div>
  2618.                                 <Table data={dataYtdPfiByProduct} />
  2619.                             </div>
  2620.                         }
  2621.                     },
  2622.                     Some(Err(_)) => {
  2623.                       view! {
  2624.                           <div>
  2625.                               <p>"Error loading data"</p>
  2626.                           </div>
  2627.                       }
  2628.                     },
  2629.                     None => {
  2630.                         view! {
  2631.                             <div>
  2632.                                 <p>"Loading data..."</p>
  2633.                             </div>
  2634.                         }
  2635.                     }
  2636.                 }
  2637.                
  2638.             }
  2639.         </Suspense>
  2640.  
  2641.         // <Table data={dataProjectedFutureIncomeByProduct} />
  2642.  
  2643.         <h2 class="title-guardian-content">Projected Future Income by Operator</h2>
  2644.         <p class="font-georgia">
  2645.           These revenue and volume averages are a one month mathematical average based on a 12 month prior period, while showing an example of what different commodity prices in the future could look like.
  2646.         </p>
  2647.  
  2648.         <p class="font-georgia mb-0">
  2649.           This information could be skewed by other products and anomalous data.
  2650.         </p>
  2651.  
  2652.         <Suspense fallback={move || view! {
  2653.             <div>
  2654.                 <TableSkeleton />
  2655.             </div>
  2656.         }}>
  2657.             {
  2658.                 move ||
  2659.                 match ytd_pfi_by_operator_resource.rows.get() {
  2660.                     Some(Ok(rows)) => {
  2661.                         let dataYtdPfiByOperator = create_ytd_pfi_by_operator_data(&rows);
  2662.                         view! {
  2663.                             <div>
  2664.                                 <Table data={dataYtdPfiByOperator} />
  2665.                             </div>
  2666.                         }
  2667.                     },
  2668.                     Some(Err(_)) => {
  2669.                       view! {
  2670.                           <div>
  2671.                               <p>"Error loading data"</p>
  2672.                           </div>
  2673.                       }
  2674.                     },
  2675.                     None => {
  2676.                         view! {
  2677.                             <div>
  2678.                                 <p>"Loading data..."</p>
  2679.                             </div>
  2680.                         }
  2681.                     }
  2682.                 }
  2683.                
  2684.             }
  2685.         </Suspense>
  2686.         // <Table data={dataProjectedFutureIncomeByOperator} />
  2687.       </div>
  2688.     }
  2689. }
  2690.  
  2691. fn create_ytd_current_data(rows: &Vec<YTDCurrentYearRow>) -> TableData {
  2692.     TableData {
  2693.         headers: vec![
  2694.             view! { <p>"Month"</p> }.into_view(),
  2695.             view! { <p>"Gross"<br />"Revenue"</p> }.into_view(),
  2696.             view! { <p>"Taxes"</p> }.into_view(),
  2697.             view! { <p>"Deductions"</p> }.into_view(),
  2698.             view! { <p>"Depletion" <br/> "15%"</p> }.into_view(),
  2699.             view! { <p>"Net" <br/> "Revenue"</p> }.into_view(),
  2700.             view! { <p>"Net Post-"<br />"Depletion" <br/> "15%"</p> }.into_view(),
  2701.             view! { <p>"Depletion"<br />"27.5%"</p> }.into_view(),
  2702.             view! { <p>"Net Post-"<br />"Depletion"<br />"27.5%"</p> }.into_view(),
  2703.         ],
  2704.         rows: rows.iter().map(|row| {
  2705.             vec![
  2706.                 view! { <p>{row.month.clone()}</p> }.into_view(),
  2707.                 view! { <p>{row.gross_revenue.clone()}</p> }.into_view(),
  2708.                 view! { <p>{row.taxes.clone()}</p> }.into_view(),
  2709.                 view! { <p>{row.deductions.clone()}</p> }.into_view(),
  2710.                 view! { <p>{row.net_revenue.clone()}</p> }.into_view(),
  2711.                 view! { <p>{row.depletion_15.clone()}</p> }.into_view(),
  2712.                 view! { <p>{row.net_post_depletion_15.clone()}</p> }.into_view(),
  2713.                 view! { <p>{row.depletion_275.clone()}</p> }.into_view(),
  2714.                 view! { <p>{row.net_post_depletion_275.clone()}</p> }.into_view(),
  2715.             ]
  2716.         }).collect::<Vec<_>>(),
  2717.         links: vec![None, None],
  2718.         has_totals: true,
  2719.     }
  2720. }
  2721.  
  2722. fn create_ytd_past_tax_year_data(rows: &Vec<YTDPastTaxYearRow>) -> TableData {
  2723.     TableData {
  2724.         headers: vec![
  2725.             view! { <p>"Month"</p> }.into_view(),
  2726.             view! { <p>"Gross"<br />"Revenue"</p>  }.into_view(),
  2727.             view! { <p>"Taxes"</p> }.into_view(),
  2728.             view! { <p>"Deductions"</p> }.into_view(),
  2729.             view! { <p>"Net" <br/> "Revenue"</p> }.into_view(),
  2730.             view! { <p>"Depletion" <br/> "15%"</p> }.into_view(),
  2731.             view! { <p>"Net Post-"<br />"Depletion" <br/> "15%"</p> }.into_view(),
  2732.             view! { <p>"Depletion"<br />"27.5%"</p> }.into_view(),
  2733.             view! { <p>"Net Post-"<br />"Depletion"<br />"27.5%"</p> }.into_view(),
  2734.         ],
  2735.         rows: rows.iter().map(|row| {
  2736.             vec![
  2737.                 view! { <p>{row.month.clone()}</p> }.into_view(),
  2738.                 view! { <p>{row.gross_revenue.clone()}</p> }.into_view(),
  2739.                 view! { <p>{row.taxes.clone()}</p> }.into_view(),
  2740.                 view! { <p>{row.deductions.clone()}</p> }.into_view(),
  2741.                 view! { <p>{row.net_revenue.clone()}</p> }.into_view(),
  2742.                 view! { <p>{row.depletion_15.clone()}</p> }.into_view(),
  2743.                 view! { <p>{row.net_post_depletion_15.clone()}</p> }.into_view(),
  2744.                 view! { <p>{row.depletion_275.clone()}</p> }.into_view(),
  2745.                 view! { <p>{row.net_post_depletion_275.clone()}</p> }.into_view(),
  2746.             ]
  2747.         }).collect::<Vec<_>>(),
  2748.         links: vec![None, None],
  2749.         has_totals: true,
  2750.     }
  2751. }
  2752.  
  2753. fn create_ytd_pfi_by_operator_data(rows: &Vec<YTDPFIByOperatorRow>) -> TableData {
  2754.     TableData {
  2755.         headers: vec![
  2756.             view! { <p>"Operator"</p> }.into_view(),
  2757.             view! { <p>"Oil"<br />"Volume"<br />"(bbl)"</p> }.into_view(),
  2758.             view! { <p>"Natural Gas"<br />"Volume"<br />"(mcf)"</p> }.into_view(),
  2759.             view! { <p>"Oil"<br />"Revenue"<br />"$60"</p> }.into_view(),
  2760.             view! { <p>"Oil"<br />"Revenue"<br />"$75"</p> }.into_view(),
  2761.             view! { <p>"Oil"<br />"Revenue"<br />"$90"</p> }.into_view(),
  2762.             view! { <p>"Gas"<br />"Revenue"<br />"$2"</p> }.into_view(),
  2763.             view! { <p>"Gas"<br />"Revenue"<br />"$2.50"</p> }.into_view(),
  2764.             view! { <p>"Gas"<br />"Revenue"<br />"$3"</p> }.into_view(),
  2765.         ],
  2766.         rows: rows.iter().map(|row| {
  2767.             vec![
  2768.                 view! { <p>{row.operator_purchaser.clone()}</p> }.into_view(),
  2769.                 view! { <p>{row.oil_volume.clone()}</p> }.into_view(),
  2770.                 view! { <p>{row.natural_gas_volume.clone()}</p> }.into_view(),
  2771.                 view! { <p>{row.oil_volume_60.clone()}</p> }.into_view(),
  2772.                 view! { <p>{row.oil_volume_75.clone()}</p> }.into_view(),
  2773.                 view! { <p>{row.oil_volume_90.clone()}</p> }.into_view(),
  2774.                 view! { <p>{row.natural_gas_volume_2.clone()}</p> }.into_view(),
  2775.                 view! { <p>{row.natural_gas_volume_25.clone()}</p> }.into_view(),
  2776.                 view! { <p>{row.natural_gas_volume_3.clone()}</p> }.into_view(),
  2777.             ]
  2778.         }).collect::<Vec<_>>(),
  2779.         links: vec![None, None],
  2780.         has_totals: true,
  2781.     }
  2782. }
  2783.  
  2784. fn create_ytd_pfi_by_product_data(rows: &Vec<YTDPFIByProductRow>) -> TableData {
  2785.     TableData {
  2786.         headers: vec![
  2787.             view! { <p>"Product"</p> }.into_view(),
  2788.             view! { <p>"Last Month"</p> }.into_view(),
  2789.             view! { <p>"3 Months"</p> }.into_view(),
  2790.             view! { <p>"6 Months"</p> }.into_view(),
  2791.             view! { <p>"12 Months"</p> }.into_view(),
  2792.         ],
  2793.         rows: rows.iter().map(|row| {
  2794.             vec![
  2795.                 view! { <p>{row.product_category.clone()}</p> }.into_view(),
  2796.                 view! { <p>{row.last_month_avg_share_net.clone()}</p> }.into_view(),
  2797.                 view! { <p>{row.three_months_avg_share_net.clone()}</p> }.into_view(),
  2798.                 view! { <p>{row.six_months_avg_share_net.clone()}</p> }.into_view(),
  2799.                 view! { <p>{row.twelve_months_avg_share_net.clone()}</p> }.into_view(),
  2800.             ]
  2801.         }).collect::<Vec<_>>(),
  2802.         links: vec![None, None],
  2803.         has_totals: true,
  2804.     }
  2805. }
  2806.  
  2807. fn create_ytd_revenue_by_operator_data(rows: &Vec<YTDRevenueByOperatorRow>) -> TableData {
  2808.     TableData {
  2809.         headers: vec![
  2810.             view! { <p>"Operator"</p> }.into_view(),
  2811.             view! { <p>"Owner Net Revenue"</p> }.into_view(),
  2812.         ],
  2813.         rows: rows.iter().map(|row| {
  2814.             vec![
  2815.                 view! { <p>{row.operator_purchaser.clone()}</p> }.into_view(),
  2816.                 view! { <p>{row.total_share_net.clone()}</p> }.into_view(),
  2817.             ]
  2818.         }).collect::<Vec<_>>(),
  2819.         links: vec![None, None],
  2820.         has_totals: true,
  2821.     }
  2822. }
  2823.  
  2824. ================
  2825. File: gmm_client/src/server/app_pools.rs
  2826. ================
  2827. #[cfg(feature = "ssr")]
  2828. pub mod ssr {
  2829.     use crate::{
  2830.         server::initialize_test_data::ssr::initialize_test_data, // Import the function from ssr module
  2831.         // server::land_migration::ssr::land_migration, // Import the land_migration function
  2832.         server::load_accounts_configuration::ssr::load_accounts_configuration,
  2833.         server::load_admins_configuration::ssr::load_admins_configuration,
  2834.         server::open::ssr::open_read_only_land_pool,
  2835.     };
  2836.     use sqlx::migrate::MigrateDatabase;
  2837.     use sqlx::sqlite::SqlitePoolOptions;
  2838.     use sqlx::SqlitePool;
  2839.     use std::fs;
  2840.  
  2841.     #[derive(Debug, Clone)]
  2842.     pub struct AppPools {
  2843.         pub app_pool: SqlitePool,
  2844.         pub land_pool: SqlitePool,
  2845.     }
  2846.  
  2847.     use leptos::*;
  2848.  
  2849.     pub fn app_pools() -> Result<AppPools, ServerFnError> {
  2850.         use_context::<AppPools>()
  2851.             .ok_or_else(|| ServerFnError::ServerError("App Pools missing.".into()))
  2852.     }
  2853.  
  2854.     impl AppPools {
  2855.         pub async fn new() -> AppPools {
  2856.             // Create db directory if it doesn't exist
  2857.             if let Err(e) = fs::create_dir_all("db") {
  2858.                 panic!("Failed to create db directory: {:?}", e);
  2859.             }
  2860.  
  2861.             // Create db directory if it doesn't exist
  2862.             if let Err(e) = fs::create_dir_all("db") {
  2863.                 panic!("Failed to create db directory: {:?}", e);
  2864.             }
  2865.  
  2866.             // App database setup
  2867.             let db_url = "sqlite:db/GmmClient04.db?mode=rwc";
  2868.             if !sqlx::Sqlite::database_exists(db_url)
  2869.                 .await
  2870.                 .unwrap_or(false)
  2871.             {
  2872.                 println!("Creating app database");
  2873.                 match sqlx::Sqlite::create_database(db_url).await {
  2874.                     Ok(_) => println!("App database created successfully"),
  2875.                     Err(error) => panic!("Error creating app database: {:?}", error),
  2876.                 }
  2877.             }
  2878.  
  2879.             let app_pool = SqlitePoolOptions::new()
  2880.                 .connect(db_url)
  2881.                 .await
  2882.                 .expect("Could not connect to app database");
  2883.  
  2884.             // Land database setup (keep as is)
  2885.             // let land_db_path = "land_db/land.db";
  2886.  
  2887.             let app_db_path = "app_db/bridge.db";
  2888.  
  2889.             // land_migration(land_db_path).await.unwrap();
  2890.             let rw_land_pool = SqlitePoolOptions::new()
  2891.                 .connect(&format!("sqlite:{}?mode=rw", app_db_path))
  2892.                 .await
  2893.                 .expect("Could not connect to land database.");
  2894.  
  2895.             if let Err(e) = sqlx::migrate!().run(&app_pool).await {
  2896.                 eprintln!("{e:?}");
  2897.             }
  2898.  
  2899.             let test_app_pools = AppPools {
  2900.                 app_pool: app_pool.clone(),
  2901.                 land_pool: rw_land_pool.clone(),
  2902.             };
  2903.  
  2904.             // Initialize test data after migrations
  2905.             initialize_test_data(&test_app_pools)
  2906.                 .await
  2907.                 .expect("Failed to initialize test data");
  2908.  
  2909.             // initialize_indexes(&rw_land_pool)
  2910.             //     .await
  2911.             //     .expect("Could not create indexes");
  2912.  
  2913.             // Close the temporary read-write land pool before reopening in read-only mode
  2914.             rw_land_pool.close().await;
  2915.  
  2916.             let land_pool = open_read_only_land_pool(app_db_path).await;
  2917.  
  2918.             let app_pools = AppPools {
  2919.                 app_pool: app_pool.clone(),
  2920.                 land_pool: land_pool.clone(),
  2921.             };
  2922.             load_accounts_configuration(&app_pools)
  2923.                 .await
  2924.                 .expect("Failed to load accounts configuration");
  2925.             load_admins_configuration(&app_pools)
  2926.                 .await
  2927.                 .expect("Failed to load admins configuration");
  2928.  
  2929.             app_pools
  2930.         }
  2931.     }
  2932. }
  2933.  
  2934.  
  2935.  
  2936.  
  2937. ================================================================
  2938. End of Codebase
  2939. ================================================================
  2940.  
Add Comment
Please, Sign In to add comment