You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

244 lines
5.9 KiB

  1. <script lang="ts">
  2. import { onMount } from "svelte";
  3. import { endOfDay, endOfMonth, endOfWeek, endOfYear, formatFormTime, lastMonth, lastYear, monthName, nextMonth, nextYear, startOfDay, startOfMonth, startOfWeek, startOfYear } from "../utils/time";
  4. import EveryMinute from "./EveryMinute.svelte";
  5. interface DateOption {
  6. id: string
  7. label: string
  8. from: Date
  9. to: Date
  10. }
  11. export let fromValue: string;
  12. export let toValue: string;
  13. export let disabled: boolean = false;
  14. export let styled: boolean;
  15. export let noFuture: boolean;
  16. export let label: string = "Time Period";
  17. let selected: string = "custom";
  18. let options: DateOption[] = [];
  19. let now: Date = new Date();
  20. onMount(() => {
  21. for (const option of options) {
  22. console.log(formatFormTime(option.from), fromValue, formatFormTime(option.to), toValue);
  23. if (formatFormTime(option.from) === fromValue && formatFormTime(option.to) === toValue) {
  24. selected = option.id;
  25. console.log("-- SELECTED")
  26. break;
  27. }
  28. }
  29. });
  30. $: {
  31. if (options.length === 0) {
  32. let current = startOfMonth(now);
  33. const nextWeek = new Date(now.getTime() + (86400000 * 7));
  34. const lastWeek = new Date(now.getTime() - (86400000 * 7));
  35. options.push({
  36. id: "this_week",
  37. label: "This Week",
  38. from: startOfWeek(now),
  39. to: endOfWeek(now),
  40. });
  41. if (!noFuture) {
  42. options.push({
  43. id: "next_week",
  44. label: "Next Week",
  45. from: startOfWeek(nextWeek),
  46. to: endOfWeek(nextWeek),
  47. });
  48. options.push({
  49. id: "next_7days",
  50. label: "Next 7 Days",
  51. from: startOfDay(now),
  52. to: endOfDay(new Date(now.getTime() + 86400000 * 7)),
  53. });
  54. }
  55. options.push({
  56. id: "last_week",
  57. label: "Last Week",
  58. from: startOfWeek(lastWeek),
  59. to: endOfWeek(lastWeek),
  60. });
  61. options.push({
  62. id: "last_7days",
  63. label: "Last 7 Days",
  64. from: startOfDay(new Date(now.getTime() - 86400000 * 7)),
  65. to: endOfDay(now),
  66. });
  67. options.push({
  68. id: "this_month",
  69. label: "This Month",
  70. from: current,
  71. to: endOfMonth(current),
  72. });
  73. if (!noFuture) {
  74. options.push({
  75. id: "next_month",
  76. label: "Next Month",
  77. from: nextMonth(current),
  78. to: endOfMonth(nextMonth(current)),
  79. });
  80. options.push({
  81. id: "next_30days",
  82. label: "Next 30 Days",
  83. from: startOfDay(now),
  84. to: endOfDay(new Date(now.getTime() + 86400000 * 30)),
  85. });
  86. options.push({
  87. id: "next_90days",
  88. label: "Next 90 Days",
  89. from: startOfDay(now),
  90. to: endOfDay(new Date(now.getTime() + 86400000 * 90)),
  91. });
  92. }
  93. options.push({
  94. id: "last_month",
  95. label: "Last Month",
  96. from: lastMonth(current),
  97. to: endOfMonth(lastMonth(current)),
  98. });
  99. options.push({
  100. id: "last_30days",
  101. label: "Last 30 Days",
  102. from: startOfDay(new Date(now.getTime() - 86400000 * 30)),
  103. to: endOfDay(now),
  104. });
  105. options.push({
  106. id: "last_90days",
  107. label: "Last 90 Days",
  108. from: startOfDay(new Date(now.getTime() - 86400000 * 90)),
  109. to: endOfDay(now),
  110. });
  111. options.push({
  112. id: "this_year",
  113. label: "This Year",
  114. from: startOfYear(now),
  115. to: endOfYear(now),
  116. });
  117. if (!noFuture) {
  118. options.push({
  119. id: "next_year",
  120. label: "Next Year",
  121. from: startOfYear(nextYear(now)),
  122. to: endOfYear(nextYear(now, 2)),
  123. });
  124. options.push({
  125. id: "next_1year",
  126. label: "Next 1 Year",
  127. from: startOfDay(now),
  128. to: endOfDay(nextYear(now)),
  129. });
  130. }
  131. options.push({
  132. id: "last_year",
  133. label: "Last Year",
  134. from: startOfYear(lastYear(now)),
  135. to: endOfYear(lastYear(now)),
  136. });
  137. options.push({
  138. id: "last_1year",
  139. label: "Last 1 Year",
  140. from: startOfDay(lastYear(now)),
  141. to: endOfDay(now),
  142. });
  143. options.push({
  144. id: "custom",
  145. label: "Specific Dates",
  146. from: null,
  147. to: null,
  148. });
  149. console.log(options);
  150. }
  151. }
  152. $: {
  153. if (selected !== "custom") {
  154. const option = options.find(o => o.id === selected);
  155. if (option != null) {
  156. fromValue = formatFormTime(option.from);
  157. toValue = formatFormTime(option.to);
  158. }
  159. }
  160. }
  161. </script>
  162. <EveryMinute bind:now={now} />
  163. <div class:styled>
  164. <div>
  165. <label for="timeRange">{label}</label>
  166. <select name="timeRange" disabled={disabled} bind:value={selected}>
  167. {#each options as option (option.id)}
  168. <option value={option.id}>{option.label}</option>
  169. {/each}
  170. </select>
  171. </div>
  172. {#if selected === "custom"}
  173. <div>
  174. <label for="startTime">Start Time</label>
  175. <input disabled={disabled} name="startTime" type="datetime-local" bind:value={fromValue} />
  176. </div>
  177. <div>
  178. <label for="endTime">End Time</label>
  179. <input disabled={disabled} name="endTime" type="datetime-local" bind:value={toValue} />
  180. </div>
  181. {/if}
  182. </div>
  183. <style>
  184. div.styled {
  185. display: flex;
  186. flex-direction: row;
  187. width: 100%;
  188. }
  189. div.styled > div:first {
  190. width: 20%;
  191. }
  192. div.styled > div {
  193. padding: 0.5em;
  194. margin: 0 auto;
  195. width: 35%;
  196. }
  197. div.styled select, div.styled input {
  198. width: 100%;
  199. margin-bottom: 0.5em;
  200. background: #222;
  201. color: #777;
  202. border: none;
  203. outline: none;
  204. resize: vertical;
  205. }
  206. div.styled select {
  207. padding: 0.46em 0.5ch;
  208. }
  209. div.styled input:focus, div.styled select:focus {
  210. background: #191919;
  211. color: #CCC;
  212. border: none;
  213. outline: none;
  214. }
  215. @media screen and (max-width: 900px) {
  216. div.styled {
  217. flex-direction: column;
  218. margin-bottom: 1em;
  219. }
  220. div.styled > div {
  221. width: 90%;
  222. }
  223. }
  224. </style>