import clsx from "clsx"
import { useEffect, useMemo, useRef, useState } from "react"
import Chart from "react-google-charts"
import { Button } from "~/components/button"
import { ApplicationList } from "~/home/application-list"
import type { Node } from "~/home/graph"
import { useRootStore } from "~/home/store"
import { Queue } from "~/queue"
import { useUiMode } from "~/use-ui-mode"
export function meta() {
return [
{ title: "TrackMyApp" },
{
name: "description",
content: "Track and visualize your job applications and more.",
},
]
}
export default function Home() {
const loadGraphFromLocalStorage = useRootStore(
(state) => state.loadGraphFromLocalStorage,
)
useEffect(function saveGraphToLocalStorage() {
const unsub = useRootStore.subscribe(({ nodes, starts, entries }) => {
localStorage.setItem("graph", JSON.stringify({ nodes, starts, entries }))
})
return () => {
unsub()
}
}, [])
useEffect(() => {
if (!loadGraphFromLocalStorage()) {
alert("Unable to load locally saved data due to inconsistency.")
}
}, [loadGraphFromLocalStorage])
return (
)
}
function FlufferChart() {
const nodes = useRootStore((state) => state.nodes)
const starts = useRootStore((state) => state.starts)
const resetGraph = useRootStore((state) => state.resetGraph)
const uiMode = useUiMode()
const data = useMemo(() => {
try {
const rows: [string, string, number][] = []
const queue = new Queue()
for (const nodeKey of starts) {
queue.enqueue(nodes[nodeKey])
}
while (!queue.isEmpty) {
// biome-ignore lint/style/noNonNullAssertion: if queue is non empty, then dequeue will always be non null
const currentNode = queue.dequeue()!
for (const nodeKey in currentNode.outs) {
// biome-ignore lint/style/noNonNullAssertion:
const connection = currentNode.outs[nodeKey]!
rows.push([currentNode.key, connection.nodeKey, connection.weight])
queue.enqueue(nodes[connection.nodeKey])
}
}
return rows
} catch {
if (confirm("Invalid data detected. Erase data and reset?")) {
resetGraph()
}
return []
}
}, [starts, nodes, resetGraph])
const hasData = data.length > 0
return (
{hasData ? null : (
Enter some data to see the graph here.
)}
)
}
function AddApplicationForm() {
const [isAddingEntry, setIsAddingEntry] = useState(false)
const addEntry = useRootStore((state) => state.addEntry)
const hasEntry = useRootStore((state) => state.hasEntry)
const inputRef = useRef(null)
useEffect(() => {
if (isAddingEntry) {
inputRef.current?.focus()
}
}, [isAddingEntry])
function onAddButtonClick() {
if (!isAddingEntry) {
setIsAddingEntry(true)
} else if (inputRef.current) {
const entryName = inputRef.current.value
if (hasEntry(entryName)) {
alert(`There is already an application named ${entryName}!`)
} else {
addEntry(entryName)
setIsAddingEntry(false)
}
}
}
function cancelEntry() {
setIsAddingEntry(false)
}
return (
{isAddingEntry ? (
{
if (event.key === "Enter") {
onAddButtonClick()
}
}}
/>
) : null}
{isAddingEntry ? : null}
)
}