112 lines
2.8 KiB
TypeScript
112 lines
2.8 KiB
TypeScript
import { Box, useApp, useInput } from "ink";
|
|
import { use, useState, type ComponentType, type ReactNode } from "react";
|
|
import { ListBox } from "./components/ui/ListBox.js";
|
|
import type { DbInterface } from "../db/types/DbInterface.js";
|
|
import { DbProvider } from "../react/contexts/Db.js";
|
|
import { UsersPanel } from "./components/panels/UsersPanel.js";
|
|
import { BgColorContext } from "./contexts/BgColor.js";
|
|
import { FocusManager, useActive } from "./contexts/FocusManager.js";
|
|
import { Provider } from "../react/store/react.js";
|
|
import { createStore, type Store } from "../react/store/store.js";
|
|
import { AbodesPanel } from "./components/panels/AbodesPanel.js";
|
|
import { LoginPanel } from "./components/panels/LoginPanel.js";
|
|
import { PopupManager } from "../react/contexts/PopupManager.js";
|
|
|
|
function AppWrapper({
|
|
children,
|
|
db,
|
|
store,
|
|
bgColor,
|
|
}: {
|
|
children: ReactNode;
|
|
db: DbInterface;
|
|
store: Store;
|
|
bgColor?: string;
|
|
}) {
|
|
return (
|
|
<FocusManager>
|
|
<Provider store={store}>
|
|
<DbProvider db={db}>
|
|
<BgColorContext value={bgColor ?? use(BgColorContext)}>
|
|
<Box flexGrow={1} flexDirection="column">
|
|
<Box height={1} />
|
|
<Box alignItems="stretch" flexGrow={1}>
|
|
<PopupManager>{children}</PopupManager>
|
|
</Box>
|
|
</Box>
|
|
</BgColorContext>
|
|
</DbProvider>
|
|
</Provider>
|
|
</FocusManager>
|
|
);
|
|
}
|
|
|
|
export type CollectionType = "users" | "abodes" | "apikeys" | "notes";
|
|
const collectionTypes: CollectionType[] = [
|
|
"users",
|
|
"abodes",
|
|
"apikeys",
|
|
"notes",
|
|
];
|
|
const collectionTypeDisplay: Record<CollectionType, string> = {
|
|
users: "Users",
|
|
abodes: "Abodes",
|
|
apikeys: "API Keys",
|
|
notes: "Notes",
|
|
};
|
|
|
|
const collections: Record<CollectionType, ComponentType> = {
|
|
users: UsersPanel,
|
|
abodes: AbodesPanel,
|
|
apikeys: () => null,
|
|
notes: () => null,
|
|
};
|
|
|
|
function App() {
|
|
const app = useApp();
|
|
const isActive = useActive();
|
|
useInput(
|
|
(input, key) => {
|
|
if (input === "q" || key.escape) app.exit();
|
|
},
|
|
{ isActive }
|
|
);
|
|
|
|
const [activeCollection, setActiveCollection] =
|
|
useState<CollectionType>("users");
|
|
const CollectionPanel = collections[activeCollection];
|
|
return (
|
|
<Box flexGrow={1} flexDirection="row">
|
|
<ListBox
|
|
width={13}
|
|
title="Collections"
|
|
items={collectionTypes}
|
|
display={collectionTypeDisplay}
|
|
autoFocus
|
|
selected={activeCollection}
|
|
setSelected={setActiveCollection}
|
|
/>
|
|
<Box flexGrow={1} flexDirection="column">
|
|
<LoginPanel />
|
|
<CollectionPanel />
|
|
</Box>
|
|
</Box>
|
|
);
|
|
}
|
|
|
|
export function app({
|
|
db,
|
|
bgColor,
|
|
store = createStore(),
|
|
}: {
|
|
db: DbInterface;
|
|
bgColor?: string;
|
|
store?: Store;
|
|
}) {
|
|
return (
|
|
<AppWrapper db={db} store={store} bgColor={bgColor}>
|
|
<App />
|
|
</AppWrapper>
|
|
);
|
|
}
|