diff options
| author | Ellie Huxtable <ellie@elliehuxtable.com> | 2024-04-17 14:06:05 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-04-17 14:06:05 +0100 |
| commit | cb19925011d889c513e1bbedc446e399597e38a0 (patch) | |
| tree | 7ad9e42013e15957805f2cdf563ce8b3e0c770f5 /ui/src/pages | |
| parent | chore(deps): bump debian (#1947) (diff) | |
| download | atuin-cb19925011d889c513e1bbedc446e399597e38a0.zip | |
feat(gui): work on home page, sort state (#1956)
1. Start on a home page, can sort onboarding/etc from there
2. Introduce zustand for state management. It's nice!
Did a production build and clicked around for a while. Memory usage
seems nice and chill.
Diffstat (limited to 'ui/src/pages')
| -rw-r--r-- | ui/src/pages/Dotfiles.tsx | 7 | ||||
| -rw-r--r-- | ui/src/pages/History.tsx | 45 | ||||
| -rw-r--r-- | ui/src/pages/Home.tsx | 84 |
3 files changed, 92 insertions, 44 deletions
diff --git a/ui/src/pages/Dotfiles.tsx b/ui/src/pages/Dotfiles.tsx index bd209062..6b0870b3 100644 --- a/ui/src/pages/Dotfiles.tsx +++ b/ui/src/pages/Dotfiles.tsx @@ -1,12 +1,5 @@ -import { useState } from "react"; - -import { Cog6ToothIcon } from "@heroicons/react/24/outline"; - import Aliases from "@/components/dotfiles/Aliases"; -import { Drawer } from "@/components/drawer"; -import { invoke } from "@tauri-apps/api/core"; - function Header() { return ( <div className="md:flex md:items-center md:justify-between"> diff --git a/ui/src/pages/History.tsx b/ui/src/pages/History.tsx index f74c16ac..91ed9824 100644 --- a/ui/src/pages/History.tsx +++ b/ui/src/pages/History.tsx @@ -1,40 +1,10 @@ -import { Fragment, useState, useEffect } from "react"; -import { Dialog, Transition } from "@headlessui/react"; -import { - Bars3Icon, - ChartPieIcon, - Cog6ToothIcon, - HomeIcon, - XMarkIcon, -} from "@heroicons/react/24/outline"; - -import Logo from "../assets/logo-light.svg"; - -import { invoke } from "@tauri-apps/api/core"; +import { useEffect } from "react"; import HistoryList from "@/components/HistoryList.tsx"; import HistorySearch from "@/components/HistorySearch.tsx"; import Stats from "@/components/history/Stats.tsx"; import Drawer from "@/components/Drawer.tsx"; - -function refreshHistory( - setHistory: React.Dispatch<React.SetStateAction<never[]>>, - query: String | null, -) { - if (query) { - invoke("search", { query: query }) - .then((res: any[]) => { - setHistory(res); - }) - .catch((e) => { - console.log(e); - }); - } else { - invoke("list").then((h: any[]) => { - setHistory(h); - }); - } -} +import { useStore } from "@/state/store"; function Header() { return ( @@ -44,7 +14,7 @@ function Header() { Shell History </h2> </div> - <div className="mt-4 flex md:ml-4 md:mt-0"> + <div className="flex"> <Drawer width="70%" trigger={ @@ -77,10 +47,11 @@ function Header() { } export default function Search() { - let [history, setHistory] = useState([]); + const history = useStore((state) => state.shellHistory); + const refreshHistory = useStore((state) => state.refreshShellHistory); useEffect(() => { - refreshHistory(setHistory, null); + refreshHistory(); }, []); return ( @@ -93,8 +64,8 @@ export default function Search() { <div className="flex h-16 shrink-0 items-center gap-x-4 border-b border-t border-gray-200 bg-white px-4 shadow-sm sm:gap-x-6 sm:px-6 lg:px-8"> <HistorySearch - refresh={(query: String | null) => { - refreshHistory(setHistory, query); + refresh={(query?: string) => { + refreshHistory(query); }} /> </div> diff --git a/ui/src/pages/Home.tsx b/ui/src/pages/Home.tsx new file mode 100644 index 00000000..c0f8fbc5 --- /dev/null +++ b/ui/src/pages/Home.tsx @@ -0,0 +1,84 @@ +import { useEffect } from "react"; +import { formatRelative } from "date-fns"; + +import { useStore } from "@/state/store"; + +function Stats({ stats }: any) { + return ( + <div> + <dl className="mt-5 grid grid-cols-1 gap-5 sm:grid-cols-3"> + {stats.map((item: any) => ( + <div + key={item.name} + className="overflow-hidden rounded-lg bg-white px-4 py-5 shadow sm:p-6" + > + <dt className="truncate text-sm font-medium text-gray-500"> + {item.name} + </dt> + <dd className="mt-1 text-3xl font-semibold tracking-tight text-gray-900"> + {item.stat} + </dd> + </div> + ))} + </dl> + </div> + ); +} + +function Header({ name }: any) { + let greeting = name && name.length > 0 ? "Hey, " + name + "!" : "Hey!"; + + return ( + <div className="md:flex md:items-center md:justify-between"> + <div className="min-w-0 flex-1"> + <h2 className="text-2xl font-bold leading-7 text-gray-900 sm:truncate sm:text-3xl sm:tracking-tight"> + {greeting} + </h2> + <h3 className="text-xl leading-7 text-gray-900 pt-4"> + Welcome to Atuin. + </h3> + </div> + </div> + ); +} + +export default function Home() { + const homeInfo = useStore((state) => state.homeInfo); + const refreshHomeInfo = useStore((state) => state.refreshHomeInfo); + + useEffect(() => { + refreshHomeInfo(); + }, []); + + if (!homeInfo) { + return <div>Loading...</div>; + } + + return ( + <div className="pl-60"> + <div className="p-10"> + <Header name={"Ellie"} /> + + <div className="pt-10"> + <h2 className="text-xl font-bold">Sync</h2> + <Stats + stats={[ + { + name: "Last Sync", + stat: formatRelative(homeInfo.lastSyncTime, new Date()), + }, + { + name: "Total history records", + stat: homeInfo.historyCount.toLocaleString(), + }, + { + name: "Other records", + stat: homeInfo.recordCount - homeInfo.historyCount, + }, + ]} + /> + </div> + </div> + </div> + ); +} |
