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 (

TrackMyApp

My Applications

) } 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}
) }