{"version":3,"file":"js/app.38e0ca36.js","mappings":"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","sources":["webpack://python-webpack-boilerplate/./frontend/src/utils/hijack.js","webpack://python-webpack-boilerplate/./frontend/src/utils/sorttable.js","webpack://python-webpack-boilerplate/./frontend/src/utils/spark.js","webpack://python-webpack-boilerplate/./frontend/src/utils/image.js","webpack://python-webpack-boilerplate/./frontend/src/utils/menu.js","webpack://python-webpack-boilerplate/./frontend/src/context/UserContextProvider.js","webpack://python-webpack-boilerplate/./frontend/src/components/ErrorBoundary.js","webpack://python-webpack-boilerplate/./frontend/src/components/UserMenu.js","webpack://python-webpack-boilerplate/./frontend/src/components/Clock.js","webpack://python-webpack-boilerplate/./frontend/src/application/app.js","webpack://python-webpack-boilerplate/./frontend/src/dataComponents.js","webpack://python-webpack-boilerplate/./frontend/src/utils/selected.js","webpack://python-webpack-boilerplate/./frontend/src/utils/chart.js"],"sourcesContent":["var myModal = document.getElementById(\"hijackModal\");\nif (myModal) {\n  myModal.addEventListener(\"show.bs.modal\", function (event) {\n    var button = event.relatedTarget;\n    var userId = button.getAttribute(\"data-userid\");\n    var userName = button.getAttribute(\"data-username\");\n    var form = myModal.querySelector(\"#hijack-user\");\n    // Update form elements\n    form.querySelector('input[name=\"user_pk\"]').value = userId;\n\n    // Update modal body\n    var modalBody = myModal.querySelector(\".modal-body\");\n    modalBody.innerHTML = \"Hijack \" + userName + \"?\";\n  });\n}\n","// ==============================================================\n// |                  This code was generated                   |\n// |                   by ChatGPT, an OpenAI                    |\n// |                      language model.                       |\n// ==============================================================\n\nconst table = document.getElementById(\"table-select\");\nif (table) {\n  const tbody = table.getElementsByTagName(\"tbody\")[0];\n  const rows = Array.from(tbody.getElementsByTagName(\"tr\"));\n\n  const sortTable = (columnIndex, ascending) => {\n    const isNumeric = !isNaN(\n      rows[0].getElementsByTagName(\"td\")[columnIndex].textContent\n    );\n    rows.sort((row1, row2) => {\n      const cell1 = row1.getElementsByTagName(\"td\")[columnIndex].textContent;\n      const cell2 = row2.getElementsByTagName(\"td\")[columnIndex].textContent;\n      const value1 = isNumeric ? parseInt(cell1) : cell1.toLowerCase();\n      const value2 = isNumeric ? parseInt(cell2) : cell2.toLowerCase();\n      if (value1 < value2) return ascending ? -1 : 1;\n      if (value1 > value2) return ascending ? 1 : -1;\n      return 0;\n    });\n    rows.forEach((row) => tbody.appendChild(row));\n  };\n\n  const addHeaderListeners = () => {\n    const headers = table.getElementsByTagName(\"th\");\n    Array.from(headers).forEach((header, index) => {\n      if (!header.classList.contains(\"no-sort\")) {\n        header.addEventListener(\"click\", () => {\n          const isAscending = header.getAttribute(\"data-order\") === \"asc\";\n          sortTable(index, !isAscending);\n          header.setAttribute(\"data-order\", isAscending ? \"desc\" : \"asc\");\n        });\n      }\n    });\n  };\n  addHeaderListeners();\n}\n","// Via ChatGPT\nfunction createSparkline(containerId) {\n  // Get the container element\n  var container = document.getElementById(containerId);\n\n  // Get the canvas element\n  var canvas = container.querySelector(\"canvas\");\n\n  // Get the dataset and labels from data attributes\n  var dataset = JSON.parse(canvas.getAttribute(\"data-dataset\"));\n  var labels = JSON.parse(canvas.getAttribute(\"data-labels\"));\n\n  // Get the width, height, and color from style attribute\n  var width = parseInt(canvas.style.width, 10);\n  var height = parseInt(canvas.style.height, 10);\n  var color = canvas.style.color;\n\n  // Get the 2d rendering context of the canvas\n  var ctx = canvas.getContext(\"2d\");\n\n  // Calculate the scale for x and y axes\n  var scaleX = width / (labels.length - 1);\n  var scaleY = height / (Math.max(...dataset[0]) - Math.min(...dataset[0]));\n\n  // Draw the sparkline\n  ctx.beginPath();\n  ctx.moveTo(0, height - (dataset[0][0] - Math.min(...dataset[0])) * scaleY);\n  for (var i = 1; i < labels.length; i++) {\n    ctx.lineTo(\n      i * scaleX,\n      height - (dataset[0][i] - Math.min(...dataset[0])) * scaleY\n    );\n  }\n  ctx.strokeStyle = color;\n  ctx.lineWidth = 2;\n  ctx.stroke();\n}\n\ntry {\n  createSparkline(\"sparkline1Container\");\n  createSparkline(\"sparkline2Container\");\n  createSparkline(\"sparkline3Container\");\n} catch {\n  console.log(\"error\");\n}\ntry {\n  createSparkline(\"sparkline4Container\");\n  createSparkline(\"sparkline5Container\");\n  createSparkline(\"sparkline6Container\");\n  createSparkline(\"sparkline7Container\");\n} catch {\n  console.log(\"error\");\n}\n","// Select all image links with data-bs-toggle=\"modal\"\nconst imageLinks = document.querySelectorAll('[data-bs-toggle=\"modal\"]');\n\n// Select the modal's image element\nconst modalImage = document.getElementById('modalImage');\n\n// Iterate over each image link and attach a click event listener\nimageLinks.forEach(link => {\n   link.addEventListener('shown.bs.modal', function () {\n      // Get the source URL of the clicked image\n      const imageUrl = this.querySelector('img').src;\n\n      // Set the source URL for the modal's image element\n      modalImage.src = imageUrl;\n   });\n});\n","const invoice = document.getElementById('id_invoice');\n\nif (invoice !== null) {\n    const task = document.getElementById('id_task');\n    const project = document.getElementById('id_project');\n    const client = document.getElementById('id_client');\n\n    invoice.addEventListener('change', function() {\n        var selectedIndex = this.selectedIndex;\n        task.selectedIndex = selectedIndex;\n        project.selectedIndex = selectedIndex;\n        client.selectedIndex = selectedIndex;\n    });\n}\n","// UserContextProvider.js\nimport React from 'react';\nimport { createContext, useContext, useState } from 'react';\nimport PropTypes from 'prop-types';\n\nconst UserContext = createContext();\n\nexport const UserContextProvider = ({ children }) => {\n  const [isAuthenticated, setIsAuthenticated] = useState(false);\n\n  const login = () => {\n    try {\n      // Add logic to handle login, set isAuthenticated to true\n      setIsAuthenticated(true);\n    } catch (error) {\n      console.error('Login error:', error);\n      // Handle error, e.g., show an error message to the user\n    }\n  };\n\n  const logout = () => {\n    try {\n      // Add logic to handle logout, set isAuthenticated to false\n      setIsAuthenticated(false);\n    } catch (error) {\n      console.error('Logout error:', error);\n      // Handle error, e.g., show an error message to the user\n    }\n  };\n\n  return (\n    <UserContext.Provider value={{ isAuthenticated, login, logout }}>\n      {children}\n    </UserContext.Provider>\n  );\n};\n\nUserContextProvider.propTypes = {\n  children: PropTypes.node.isRequired,\n};\n\nexport const useUserContext = () => {\n  const context = useContext(UserContext);\n\n  if (!context) {\n    throw new Error('useUserContext must be used within a UserContextProvider');\n  }\n\n  return context;\n};\n\n// Add PropTypes for the return value of useUserContext\nuseUserContext.propTypes = {\n  isAuthenticated: PropTypes.bool.isRequired,\n  login: PropTypes.func.isRequired,\n  logout: PropTypes.func.isRequired,\n};\n","import { Component } from 'react';\nimport PropTypes from 'prop-types';\n\nclass ErrorBoundary extends Component {\n  constructor (props) {\n    super(props);\n    this.state = { hasError: false };\n  }\n\n  static getDerivedStateFromError () {\n    return { hasError: true };\n  }\n\n  componentDidCatch (error, info) {\n    const { onError } = this.props;\n    console.error(error);\n    onError && onError(error, info);\n  }\n\n  render () {\n    const { children = null } = this.props;\n    const { hasError } = this.state;\n\n    return hasError ? null : children;\n  }\n}\n\nErrorBoundary.propTypes = {\n  onError: PropTypes.func,\n  children: PropTypes.node,\n};\n\nexport default ErrorBoundary;\n","// UserMenu.js\nimport React from 'react';\nimport PropTypes from 'prop-types';\n\nconst UserMenu = ({ isAuthenticated, isSuperuser }) => {\n  return (\n    <div>\n      {isAuthenticated ? (\n        <li className=\"nav-item dropdown text-nowrap\">\n          <a className=\"nav-link text-light text-uppercase exclude-from-hover\" type=\"button\" aria-expanded=\"false\" href=\"/dashboard\">\n            <i className=\"fa-solid fa-leaf me-1\"></i>\n            <span className=\"d-none d-lg-inline\">Dashboard</span>\n            <span className=\"visually-hidden\">Link text</span>\n          </a>\n          <ul className=\"dropdown-menu\">\n            <li><a className=\"dropdown-item\" href=\"/dashboard\">Overview</a></li>\n            <li><a className=\"dropdown-item\" href=\"/user/profile\">Profile</a></li>\n            <li><a className=\"dropdown-item\" href=\"/dashboard/user\">Users</a></li>\n            <li><a className=\"dropdown-item\" href=\"/dashboard/time/create/\">Add Time</a></li>\n            {isSuperuser ? (\n              <>\n                <li><hr className=\"dropdown-divider\"></hr></li>\n                <li><a className=\"dropdown-item\" href=\"https://aclarknet.signin.aws.amazon.com/console\" rel=\"noreferrer\" target=\"_blank\">AWS Console</a></li>\n                <li><a className=\"dropdown-item\" href=\"/blog\">Puput Blog</a></li>\n                <li><a className=\"dropdown-item\" href=\"/django\" rel=\"noreferrer\" target=\"_blank\">Django Admin</a></li>\n                <li><a className=\"dropdown-item\" href=\"https://analytics.google.com\" rel=\"noreferrer\" target=\"_blank\">Google Analytics</a></li>\n                <li><a className=\"dropdown-item\" href=\"https://admin.google.com/ac/home?hl=en\" rel=\"noreferrer\" target=\"_blank\">Google Workspace</a></li>\n                <li><a className=\"dropdown-item\" href=\"https://aclark.net/lounge/\" rel=\"noreferrer\" target=\"_blank\">Lounge IRC</a></li>\n                <li><a className=\"dropdown-item\" href=\"https://logfire.pydantic.dev/aclark4life/aclarknet\" rel=\"noreferrer\" target=\"_blank\">Pydantic Logfire</a></li>\n                <li><a className=\"dropdown-item\" href=\"/explorer\" rel=\"noreferrer\" target=\"_blank\">SQL Explorer</a></li>\n                <li><a className=\"dropdown-item\" href=\"/wagtail\" rel=\"noreferrer\" target=\"_blank\">Wagtail Admin</a></li>\n              </>\n            ) : null}\n            <li><hr className=\"dropdown-divider\"></hr></li>\n            <li><a className=\"dropdown-item\" href=\"/accounts/logout\">Logout</a></li>\n          </ul>\n        </li>\n      ) : (\n        <li className=\"nav-item\">\n          <a className=\"nav-link text-light text-uppercase exclude-from-hover\" href=\"/accounts/login\">\n            <i className=\"fa-solid fa-leaf me-1\"></i>\n            <span className=\"visually-hidden\">Link text</span>\n          </a>\n        </li>\n      )}\n    </div>\n  );\n};\n\nUserMenu.propTypes = {\n  isAuthenticated: PropTypes.bool.isRequired,\n  isSuperuser: PropTypes.bool.isRequired,\n};\n\nexport default UserMenu;\n","// Via ChatGPT\nimport { useState, useEffect, useCallback, useRef } from 'react';\nimport React from 'react';\n\nconst Clock = () => {\n  const [date, setDate] = useState(new Date());\n  const [blink, setBlink] = useState(true);\n  const timerID = useRef();\n\n  const tick = useCallback(() => {\n    setDate(new Date());\n    setBlink(prevBlink => !prevBlink);\n  }, []);\n\n  useEffect(() => {\n    timerID.current = setInterval(() => tick(), 1000);\n\n    // Return a cleanup function to be run on component unmount\n    return () => clearInterval(timerID.current);\n  }, [tick]);\n\n  const formattedDate = date.toLocaleDateString(undefined, {\n    weekday: 'short',\n    year: 'numeric',\n    month: 'short',\n    day: 'numeric',\n  });\n\n  const formattedTime = date.toLocaleTimeString(undefined, {\n    hour: 'numeric',\n    minute: 'numeric',\n  });\n\n  return (\n    <>\n      <div style={{ animation: blink ? 'blink 1s infinite' : 'none' }}><span className='me-2'>{formattedDate}</span> {formattedTime}</div>\n    </>\n  );\n};\n\nexport default Clock;\n","import React from 'react';\nimport { createRoot } from 'react-dom/client';\nimport 'bootstrap';\nimport '@fortawesome/fontawesome-free/js/fontawesome';\nimport '@fortawesome/fontawesome-free/js/solid';\nimport '@fortawesome/fontawesome-free/js/regular';\nimport '@fortawesome/fontawesome-free/js/brands';\nimport getDataComponents from '../dataComponents';\nimport UserContextProvider from '../context';\nimport * as components from '../components';\nimport \"../styles/index.scss\";\nimport \"../styles/theme-blue.scss\";\nimport \"./config\";\n\nconst { ErrorBoundary } = components;\nconst dataComponents = getDataComponents(components);\nconst container = document.getElementById('app');\nconst root = createRoot(container);\nconst App = () => (\n    <ErrorBoundary>\n      <UserContextProvider>\n        {dataComponents}\n      </UserContextProvider>\n    </ErrorBoundary>\n);\nroot.render(<App />);\n","// Via pwellever\nimport React from 'react';\nimport { createPortal } from 'react-dom';\n\nconst parseProps = data => Object.entries(data).reduce((result, [key, value]) => {\n  if (value.toLowerCase() === 'true') {\n    value = true;\n  } else if (value.toLowerCase() === 'false') {\n    value = false;\n  } else if (value.toLowerCase() === 'null') {\n    value = null;\n  } else if (!isNaN(parseFloat(value)) && isFinite(value)) {\n    // Parse numeric value\n    value = parseFloat(value);\n  } else if (\n    (value[0] === '[' && value.slice(-1) === ']') || (value[0] === '{' && value.slice(-1) === '}')\n  ) {\n    // Parse JSON strings\n    value = JSON.parse(value);\n  }\n\n  result[key] = value;\n  return result;\n}, {});\n\n// This method of using portals instead of calling ReactDOM.render on individual components\n// ensures that all components are mounted under a single React tree, and are therefore able\n// to share context.\n\nexport default function getPageComponents (components) {\n  const getPortalComponent = domEl => {\n    // The element's \"data-component\" attribute is used to determine which component to render.\n    // All other \"data-*\" attributes are passed as props.\n    const { component: componentName, ...rest } = domEl.dataset;\n    const Component = components[componentName];\n    if (!Component) {\n      console.error(`Component \"${componentName}\" not found.`);\n      return null;\n    }\n    const props = parseProps(rest);\n    domEl.innerHTML = '';\n\n    const { ErrorBoundary } = components;\n    return createPortal(\n      <ErrorBoundary>\n        <Component {...props} />\n      </ErrorBoundary>,\n      domEl,\n    );\n  };\n\n  return Array.from(document.querySelectorAll('[data-component]')).map(getPortalComponent);\n}\n","function handleSelectAll() {\n  var selectAll = document.getElementById(\"select-all\");\n  var checkboxes = document.getElementsByName(\"entry_id\");\n  checkboxes.forEach(function (checkbox) {\n    checkbox.checked = selectAll.checked;\n  });\n}\n\nfunction handleBtnVisibility() {\n  const table = document.getElementById(\"table-select\");\n  const deleteBtn = document.getElementById(\"delete-selected-btn\");\n  const archiveBtn = document.getElementById(\"archive-selected-btn\");\n  const unarchiveBtn = document.getElementById(\"unarchive-selected-btn\");\n  const htmlBtn = document.getElementById(\"html-selected-btn\");\n  const unhtmlBtn = document.getElementById(\"unhtml-selected-btn\");\n  const saveBtn = document.getElementById(\"save-selected-btn\");\n\n  if (table) {\n    table.addEventListener(\"change\", () => {\n      const checkboxes = table.querySelectorAll('tbody input[type=\"checkbox\"]');\n      const anyChecked = Array.from(checkboxes).some(\n        (checkbox) => checkbox.checked\n      );\n\n      deleteBtn.style.display = anyChecked ? \"block\" : \"none\";\n      archiveBtn.style.display = anyChecked ? \"block\" : \"none\";\n      unarchiveBtn.style.display = anyChecked ? \"block\" : \"none\";\n      htmlBtn.style.display = anyChecked ? \"block\" : \"none\";\n      unhtmlBtn.style.display = anyChecked ? \"block\" : \"none\";\n      saveBtn.style.display = anyChecked ? \"block\" : \"none\";\n    });\n  }\n}\n\nvar selectAll = document.getElementById(\"select-all\");\nif (selectAll) {\n  selectAll.addEventListener(\"click\", handleSelectAll);\n}\nhandleBtnVisibility();\n","import Chart from \"chart.js/auto\";\n\n// Declare an array to store chart instances\nvar charts = [];\n\n// Function to render charts\nfunction renderCharts() {\n  // Loop through all chart instances and destroy them\n  for (var i = 0; i < charts.length; i++) {\n    charts[i].destroy();\n  }\n  charts = [];\n\n  // Get all elements with class 'ex-graph'\n  var chartElements = document.getElementsByClassName(\"ex-graph\");\n\n  // Loop through all chart elements\n  for (var i = 0; i < chartElements.length; i++) { // eslint-disable-line no-redeclare\n    var chartElement = chartElements[i];\n\n    // Get chart type and data from data-* attributes\n    var chartType = chartElement.getAttribute(\"data-chart\");\n    var chartData = JSON.parse(chartElement.getAttribute(\"data-dataset\"));\n    var chartOptions = JSON.parse(\n      chartElement.getAttribute(\"data-dataset-options\")\n    );\n    var chartLabels = JSON.parse(chartElement.getAttribute(\"data-labels\"));\n\n    // Create chart using Chart.js\n    var ctx = chartElement.getContext(\"2d\");\n    const chart = new Chart(ctx, {\n      type: chartType,\n      data: {\n        labels: chartLabels,\n        datasets: [\n          {\n            data: chartData,\n            backgroundColor: chartOptions.backgroundColor,\n            borderColor: chartOptions.borderColor,\n          },\n        ],\n      },\n    });\n\n    // Add the chart instance to the charts array\n    charts.push(chart);\n  }\n}\n\n// Call the renderCharts function to initialize and render the charts\nrenderCharts();\n\n// Function to resize charts on window resize\nwindow.addEventListener(\"resize\", function () {\n  // Call the renderCharts function to resize the charts\n  renderCharts();\n});\n"],"names":["myModal","document","getElementById","addEventListener","event","button","relatedTarget","userId","getAttribute","userName","querySelector","value","innerHTML","table","tbody","getElementsByTagName","rows","Array","from","sortTable","columnIndex","ascending","isNumeric","isNaN","textContent","sort","row1","row2","cell1","cell2","value1","parseInt","toLowerCase","value2","forEach","row","appendChild","addHeaderListeners","headers","header","index","classList","contains","isAscending","setAttribute","createSparkline","containerId","canvas","dataset","JSON","parse","labels","width","style","height","color","ctx","getContext","scaleX","length","scaleY","Math","max","min","beginPath","moveTo","i","lineTo","strokeStyle","lineWidth","stroke","console","log","imageLinks","querySelectorAll","modalImage","link","imageUrl","this","src","invoice","task","project","client","selectedIndex","UserContext","createContext","UserContextProvider","children","isAuthenticated","setIsAuthenticated","useState","React","Provider","login","error","logout","propTypes","PropTypes","isRequired","ErrorBoundary","Component","constructor","props","super","state","hasError","getDerivedStateFromError","componentDidCatch","info","onError","render","UserMenu","isSuperuser","className","type","href","rel","target","Clock","date","setDate","Date","blink","setBlink","timerID","useRef","tick","useCallback","prevBlink","useEffect","current","setInterval","clearInterval","formattedDate","toLocaleDateString","undefined","weekday","year","month","day","formattedTime","toLocaleTimeString","hour","minute","animation","components","dataComponents","map","domEl","component","componentName","rest","data","Object","entries","reduce","result","key","parseFloat","isFinite","slice","createPortal","container","App","createRoot","selectAll","getElementsByName","checkbox","checked","deleteBtn","archiveBtn","unarchiveBtn","htmlBtn","unhtmlBtn","saveBtn","checkboxes","anyChecked","some","display","handleBtnVisibility","charts","renderCharts","destroy","chartElements","getElementsByClassName","chartElement","chartType","chartData","chartOptions","chartLabels","chart","Chart","datasets","backgroundColor","borderColor","push","window"],"ignoreList":[],"sourceRoot":""}