clenup import paths
This commit is contained in:
@@ -1,18 +0,0 @@
|
||||
import type React from "react";
|
||||
|
||||
export const Card = ({
|
||||
children,
|
||||
className,
|
||||
...rest
|
||||
}: JSX.IntrinsicElements["div"]): JSX.Element => {
|
||||
return (
|
||||
<div
|
||||
className={`flex overflow-hidden rounded-md bg-white text-sm text-black shadow-md ${
|
||||
className ?? ""
|
||||
}`}
|
||||
{...rest}
|
||||
>
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -1,10 +1,9 @@
|
||||
import type React from "react";
|
||||
|
||||
import type { Group } from "@components/CommandPalette/Index.js";
|
||||
import { Combobox } from "@headlessui/react";
|
||||
import { ChevronRightIcon } from "@heroicons/react/24/outline";
|
||||
|
||||
import type { Group } from "./Index.js";
|
||||
|
||||
export interface GroupViewProps {
|
||||
group: Group;
|
||||
}
|
||||
|
||||
@@ -18,6 +18,11 @@ import { toast } from "react-hot-toast";
|
||||
|
||||
import { useDevice } from "@app/core/providers/useDevice.js";
|
||||
import { useAppStore } from "@app/core/stores/appStore.js";
|
||||
import { GroupView } from "@components/CommandPalette/GroupView.js";
|
||||
import { NoResults } from "@components/CommandPalette/NoResults.js";
|
||||
import { PaletteTransition } from "@components/CommandPalette/PaletteTransition.js";
|
||||
import { SearchBox } from "@components/CommandPalette/SearchBox.js";
|
||||
import { SearchResult } from "@components/CommandPalette/SearchResult.js";
|
||||
import { Combobox, Dialog, Transition } from "@headlessui/react";
|
||||
import {
|
||||
ArchiveBoxXMarkIcon,
|
||||
@@ -43,12 +48,6 @@ import {
|
||||
XCircleIcon
|
||||
} from "@heroicons/react/24/outline";
|
||||
|
||||
import { GroupView } from "./GroupView.js";
|
||||
import { NoResults } from "./NoResults.js";
|
||||
import { PaletteTransition } from "./PaletteTransition.js";
|
||||
import { SearchBox } from "./SearchBox.js";
|
||||
import { SearchResult } from "./SearchResult.js";
|
||||
|
||||
export interface Group {
|
||||
name: string;
|
||||
icon: (props: React.ComponentProps<"svg">) => JSX.Element;
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
import type React from "react";
|
||||
|
||||
import { Mono } from "@components/generic/Mono.js";
|
||||
import { CommandLineIcon } from "@heroicons/react/24/outline";
|
||||
|
||||
import { Mono } from "../Mono.js";
|
||||
|
||||
export const NoResults = (): JSX.Element => {
|
||||
return (
|
||||
<div className="py-14 px-14 text-center">
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
import type React from "react";
|
||||
|
||||
import type { Group } from "@components/CommandPalette/Index.js";
|
||||
import { Combobox } from "@headlessui/react";
|
||||
import { ChevronRightIcon } from "@heroicons/react/24/outline";
|
||||
|
||||
import type { Group } from "./Index.js";
|
||||
|
||||
export interface SearchResultProps {
|
||||
group: Group;
|
||||
}
|
||||
|
||||
@@ -2,11 +2,10 @@ import type React from "react";
|
||||
|
||||
import { useAppStore } from "@app/core/stores/appStore.js";
|
||||
import { useDeviceStore } from "@app/core/stores/deviceStore.js";
|
||||
import { Mono } from "@components/generic/Mono.js";
|
||||
import { Hashicon } from "@emeraldpay/hashicon-react";
|
||||
import { CommandLineIcon, PlusIcon } from "@heroicons/react/24/outline";
|
||||
|
||||
import { Mono } from "./Mono.js";
|
||||
|
||||
export const DeviceSelector = (): JSX.Element => {
|
||||
const { getDevices } = useDeviceStore();
|
||||
const { selectedDevice, setSelectedDevice } = useAppStore();
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
import type React from "react";
|
||||
|
||||
import { useDevice } from "@app/core/providers/useDevice.js";
|
||||
|
||||
import { QRDialog } from "./QRDialog.js";
|
||||
import { QRDialog } from "@components/Dialog/QRDialog.js";
|
||||
|
||||
export const DialogManager = (): JSX.Element => {
|
||||
const { channels, config, QRDialogOpen, setQRDialogOpen } = useDevice();
|
||||
|
||||
@@ -5,14 +5,13 @@ import { fromByteArray } from "base64-js";
|
||||
import { toast } from "react-hot-toast";
|
||||
import { QRCode } from "react-qrcode-logo";
|
||||
|
||||
import { Checkbox } from "@components/form/Checkbox.js";
|
||||
import { IconButton } from "@components/form/IconButton.js";
|
||||
import { Input } from "@components/form/Input.js";
|
||||
import { Dialog } from "@headlessui/react";
|
||||
import { ClipboardIcon, XMarkIcon } from "@heroicons/react/24/outline";
|
||||
import { Protobuf } from "@meshtastic/meshtasticjs";
|
||||
|
||||
import { Checkbox } from "../form/Checkbox.js";
|
||||
import { Input } from "../form/Input.js";
|
||||
import { IconButton } from "../IconButton.js";
|
||||
|
||||
export interface ImportDialogProps {
|
||||
isOpen: boolean;
|
||||
close: () => void;
|
||||
|
||||
@@ -5,14 +5,13 @@ import { fromByteArray } from "base64-js";
|
||||
import { toast } from "react-hot-toast";
|
||||
import { QRCode } from "react-qrcode-logo";
|
||||
|
||||
import { Checkbox } from "@components/form/Checkbox.js";
|
||||
import { IconButton } from "@components/form/IconButton.js";
|
||||
import { Input } from "@components/form/Input.js";
|
||||
import { Dialog } from "@headlessui/react";
|
||||
import { ClipboardIcon, XMarkIcon } from "@heroicons/react/24/outline";
|
||||
import { Protobuf } from "@meshtastic/meshtasticjs";
|
||||
|
||||
import { Checkbox } from "../form/Checkbox.js";
|
||||
import { Input } from "../form/Input.js";
|
||||
import { IconButton } from "../IconButton.js";
|
||||
|
||||
export interface QRDialogProps {
|
||||
isOpen: boolean;
|
||||
close: () => void;
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
import type React from "react";
|
||||
import { useState } from "react";
|
||||
|
||||
import { Metrics } from "@components/Drawer/Metrics.js";
|
||||
import { Notifications } from "@components/Drawer/Notifications.js";
|
||||
import type { TabType } from "@components/generic/TabbedContent.js";
|
||||
import { Tab } from "@headlessui/react";
|
||||
import { ChevronDownIcon, ChevronUpIcon } from "@heroicons/react/24/outline";
|
||||
|
||||
import type { TabType } from "../layout/page/TabbedContent.js";
|
||||
import { Metrics } from "./Metrics.js";
|
||||
import { Notifications } from "./Notifications.js";
|
||||
|
||||
export const Drawer = (): JSX.Element => {
|
||||
const [drawerOpen, setDrawerOpen] = useState(false);
|
||||
|
||||
@@ -25,7 +24,7 @@ export const Drawer = (): JSX.Element => {
|
||||
onClick={() => {
|
||||
setDrawerOpen(true);
|
||||
}}
|
||||
className={`flex h-full cursor-pointer px-1 first:pl-2 last:pr-2 hover:bg-orange-300 ${
|
||||
className={`flex h-full cursor-pointer px-1 first:pl-2 last:pr-2 hover:bg-orange-200 hover:text-orange-700 ${
|
||||
selected ? "bg-orange-500 text-white" : "bg-white text-black"
|
||||
}`}
|
||||
>
|
||||
|
||||
@@ -1,50 +0,0 @@
|
||||
import type React from "react";
|
||||
|
||||
import { Disclosure } from "@headlessui/react";
|
||||
import { ChevronDownIcon, ChevronUpIcon } from "@heroicons/react/24/outline";
|
||||
|
||||
import { Mono } from "./Mono.js";
|
||||
|
||||
export interface DropdownProps {
|
||||
title: string;
|
||||
stat?: number;
|
||||
icon: JSX.Element;
|
||||
defaultOpen?: boolean;
|
||||
children: React.ReactNode;
|
||||
}
|
||||
|
||||
export const Dropdown = ({
|
||||
title,
|
||||
stat,
|
||||
icon,
|
||||
defaultOpen,
|
||||
children
|
||||
}: DropdownProps): JSX.Element => {
|
||||
return (
|
||||
<Disclosure defaultOpen={defaultOpen}>
|
||||
{({ open }) => (
|
||||
<>
|
||||
<Disclosure.Button className="group flex h-8 justify-between bg-slate-100 px-2 hover:bg-slate-200">
|
||||
<div className="my-auto flex gap-2 text-slate-700">
|
||||
<div className="my-auto">{icon}</div>
|
||||
<span className="text-lg font-medium">{title}</span>
|
||||
{stat !== undefined && (
|
||||
<span className="my-auto flex rounded-full bg-slate-200 px-3 py-0.5 group-hover:bg-slate-300">
|
||||
<Mono>{stat}</Mono>
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
<div className="my-auto text-slate-600">
|
||||
{open ? (
|
||||
<ChevronUpIcon className="h-5" />
|
||||
) : (
|
||||
<ChevronDownIcon className="h-5" />
|
||||
)}
|
||||
</div>
|
||||
</Disclosure.Button>
|
||||
<Disclosure.Panel>{children}</Disclosure.Panel>
|
||||
</>
|
||||
)}
|
||||
</Disclosure>
|
||||
);
|
||||
};
|
||||
@@ -1,14 +1,14 @@
|
||||
import React, { useState } from "react";
|
||||
import React from "react";
|
||||
|
||||
import { FiBluetooth, FiTerminal, FiWifi } from "react-icons/fi";
|
||||
|
||||
import { TabbedContent, TabType } from "./layout/page/TabbedContent.js";
|
||||
import { BLE } from "./PageComponents/Connect/BLE.js";
|
||||
import { HTTP } from "./PageComponents/Connect/HTTP.js";
|
||||
import { Serial } from "./PageComponents/Connect/Serial.js";
|
||||
import { TabbedContent, TabType } from "@components/generic/TabbedContent.js";
|
||||
import { BLE } from "@components/PageComponents/Connect/BLE.js";
|
||||
import { HTTP } from "@components/PageComponents/Connect/HTTP.js";
|
||||
import { Serial } from "@components/PageComponents/Connect/Serial.js";
|
||||
|
||||
export const NewDevice = () => {
|
||||
const [tabs, _setTabs] = useState<TabType[]>([
|
||||
const tabs: TabType[] = [
|
||||
{
|
||||
name: "BLE",
|
||||
icon: <FiBluetooth className="h-4" />,
|
||||
@@ -34,7 +34,7 @@ export const NewDevice = () => {
|
||||
disabledMessage:
|
||||
"WebSerial is currently only supported by Chromium based browsers: https://developer.mozilla.org/en-US/docs/Web/API/Web_Bluetooth_API#browser_compatibility"
|
||||
}
|
||||
]);
|
||||
];
|
||||
|
||||
return (
|
||||
<div className="m-auto h-96 w-96">
|
||||
|
||||
@@ -2,11 +2,11 @@ import type React from "react";
|
||||
|
||||
import { Controller, useFieldArray, useForm } from "react-hook-form";
|
||||
|
||||
import { Button } from "@app/components/Button.js";
|
||||
import { Button } from "@app/components/form/Button.js";
|
||||
import { IconButton } from "@app/components/form/IconButton.js";
|
||||
import { InfoWrapper } from "@app/components/form/InfoWrapper.js";
|
||||
import { Input } from "@app/components/form/Input.js";
|
||||
import { Toggle } from "@app/components/form/Toggle.js";
|
||||
import { IconButton } from "@app/components/IconButton.js";
|
||||
import { useAppStore } from "@app/core/stores/appStore.js";
|
||||
import { MapValidation } from "@app/validation/appConfig/map.js";
|
||||
import { Form } from "@components/form/Form";
|
||||
|
||||
@@ -5,9 +5,9 @@ import { fromByteArray, toByteArray } from "base64-js";
|
||||
import { Controller, useForm } from "react-hook-form";
|
||||
import { toast } from "react-hot-toast";
|
||||
|
||||
import { Input } from "@app/components/form/Input.js";
|
||||
import { ChannelSettingsValidation } from "@app/validation/channelSettings.js";
|
||||
import { Form } from "@components/form/Form";
|
||||
import { Input } from "@components/form/Input.js";
|
||||
import { Select } from "@components/form/Select.js";
|
||||
import { Toggle } from "@components/form/Toggle.js";
|
||||
import { useDevice } from "@core/providers/useDevice.js";
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import type React from "react";
|
||||
import { useCallback, useEffect, useState } from "react";
|
||||
|
||||
import { Mono } from "@app/components/Mono.js";
|
||||
import { Button } from "@components/Button.js";
|
||||
import { Mono } from "@app/components/generic/Mono.js";
|
||||
import { Button } from "@components/form/Button.js";
|
||||
import { useAppStore } from "@core/stores/appStore.js";
|
||||
import { useDeviceStore } from "@core/stores/deviceStore.js";
|
||||
import { subscribeAll } from "@core/subscriptions.js";
|
||||
|
||||
@@ -4,7 +4,7 @@ import { Controller, useForm, useWatch } from "react-hook-form";
|
||||
|
||||
import { Input } from "@app/components/form/Input.js";
|
||||
import { Toggle } from "@app/components/form/Toggle.js";
|
||||
import { Button } from "@components/Button.js";
|
||||
import { Button } from "@components/form/Button.js";
|
||||
import { useAppStore } from "@core/stores/appStore.js";
|
||||
import { useDeviceStore } from "@core/stores/deviceStore.js";
|
||||
import { subscribeAll } from "@core/subscriptions.js";
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import type React from "react";
|
||||
import { useCallback, useEffect, useState } from "react";
|
||||
|
||||
import { Mono } from "@app/components/Mono.js";
|
||||
import { Button } from "@components/Button.js";
|
||||
import { Mono } from "@app/components/generic/Mono.js";
|
||||
import { Button } from "@components/form/Button.js";
|
||||
import { useAppStore } from "@core/stores/appStore.js";
|
||||
import { useDeviceStore } from "@core/stores/deviceStore.js";
|
||||
import { subscribeAll } from "@core/subscriptions.js";
|
||||
|
||||
@@ -13,7 +13,7 @@ export const MapControlls = (): JSX.Element => {
|
||||
<div className="absolute right-0 top-0 z-10 m-2">
|
||||
<div className="divide-y overflow-hidden rounded-md bg-white">
|
||||
<div
|
||||
className="cursor-pointer p-3 hover:bg-orange-300"
|
||||
className="cursor-pointer p-3 hover:bg-orange-200 hover:text-orange-700"
|
||||
onClick={() => {
|
||||
map?.zoomIn();
|
||||
}}
|
||||
@@ -21,7 +21,7 @@ export const MapControlls = (): JSX.Element => {
|
||||
<MagnifyingGlassPlusIcon className="h-4 w-4" />
|
||||
</div>
|
||||
<div
|
||||
className="cursor-pointer p-3 hover:bg-orange-300"
|
||||
className="cursor-pointer p-3 hover:bg-orange-200 hover:text-orange-700"
|
||||
onClick={() => {
|
||||
map?.zoomOut();
|
||||
}}
|
||||
@@ -29,7 +29,7 @@ export const MapControlls = (): JSX.Element => {
|
||||
<MagnifyingGlassMinusIcon className="h-4 w-4" />
|
||||
</div>
|
||||
<div
|
||||
className="cursor-pointer p-3 hover:bg-orange-300"
|
||||
className="cursor-pointer p-3 hover:bg-orange-200 hover:text-orange-700"
|
||||
onClick={() => {}}
|
||||
>
|
||||
<FiCrosshair className="h-4 w-4" />
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
import type React from "react";
|
||||
|
||||
import { Message } from "@components/PageComponents/Messages/Message.js";
|
||||
import { MessageInput } from "@components/PageComponents/Messages/MessageInput.js";
|
||||
import { useDevice } from "@core/providers/useDevice.js";
|
||||
import type { Channel } from "@core/stores/deviceStore.js";
|
||||
|
||||
import { MessageInput } from "./MessageInput.js";
|
||||
|
||||
export interface ChannelChatProps {
|
||||
channel: Channel;
|
||||
}
|
||||
|
||||
@@ -2,8 +2,8 @@ import type React from "react";
|
||||
|
||||
import { useForm } from "react-hook-form";
|
||||
|
||||
import { IconButton } from "@app/components/form/IconButton.js";
|
||||
import { Input } from "@app/components/form/Input.js";
|
||||
import { IconButton } from "@app/components/IconButton.js";
|
||||
import { useDevice } from "@core/providers/useDevice.js";
|
||||
import type { Channel } from "@core/stores/deviceStore.js";
|
||||
import { MapPinIcon, PaperAirplaneIcon } from "@heroicons/react/24/outline";
|
||||
|
||||
@@ -2,7 +2,7 @@ import type React from "react";
|
||||
|
||||
import { Input } from "@app/components/form/Input.js";
|
||||
import { Select } from "@app/components/form/Select.js";
|
||||
import { Button } from "@components/Button.js";
|
||||
import { Button } from "@components/form/Button.js";
|
||||
import { useDevice } from "@core/providers/useDevice.js";
|
||||
import { renderOptions } from "@core/utils/selectEnumOptions.js";
|
||||
import { Protobuf } from "@meshtastic/meshtasticjs";
|
||||
|
||||
@@ -2,17 +2,14 @@ import type React from "react";
|
||||
|
||||
import { useDevice } from "@app/core/providers/useDevice.js";
|
||||
import { toMGRS } from "@app/core/utils/toMGRS.js";
|
||||
import { BatteryWidget } from "@components/Widgets/BatteryWidget.js";
|
||||
import { DeviceWidget } from "@components/Widgets/DeviceWidget.js";
|
||||
import { PeersWidget } from "@components/Widgets/PeersWidget.js";
|
||||
import { PositionWidget } from "@components/Widgets/PositionWidget.js";
|
||||
import { useAppStore } from "@core/stores/appStore.js";
|
||||
import { useDeviceStore } from "@core/stores/deviceStore.js";
|
||||
import { Types } from "@meshtastic/meshtasticjs";
|
||||
|
||||
import { BatteryWidget } from "./Widgets/BatteryWidget.js";
|
||||
import { ConfiguringWidget } from "./Widgets/ConfiguringWidget.js";
|
||||
import { DeviceWidget } from "./Widgets/DeviceWidget.js";
|
||||
import { NodeInfoWidget } from "./Widgets/NodeInfoWidget.js";
|
||||
import { PeersWidget } from "./Widgets/PeersWidget.js";
|
||||
import { PositionWidget } from "./Widgets/PositionWidget.js";
|
||||
|
||||
export const Sidebar = (): JSX.Element => {
|
||||
const { removeDevice } = useDeviceStore();
|
||||
const { connection, hardware, nodes, status, currentMetrics } = useDevice();
|
||||
@@ -39,7 +36,6 @@ export const Sidebar = (): JSX.Element => {
|
||||
/>
|
||||
|
||||
<div className="flex flex-col gap-3">
|
||||
<NodeInfoWidget hardware={hardware} />
|
||||
<BatteryWidget
|
||||
batteryLevel={currentMetrics.batteryLevel}
|
||||
voltage={currentMetrics.voltage}
|
||||
@@ -55,8 +51,6 @@ export const Sidebar = (): JSX.Element => {
|
||||
myNode?.data.position?.longitudeI
|
||||
)}
|
||||
/>
|
||||
|
||||
<ConfiguringWidget />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -1,119 +0,0 @@
|
||||
import React, { useEffect } from "react";
|
||||
|
||||
import { useDevice } from "@core/providers/useDevice.js";
|
||||
import { AdjustmentsHorizontalIcon } from "@heroicons/react/24/outline";
|
||||
|
||||
import { Card } from "../Card.js";
|
||||
import { Dropdown } from "../Dropdown.js";
|
||||
|
||||
export const ConfiguringWidget = (): JSX.Element => {
|
||||
const {
|
||||
hardware,
|
||||
channels,
|
||||
config,
|
||||
moduleConfig,
|
||||
setReady,
|
||||
nodes,
|
||||
connection
|
||||
} = useDevice();
|
||||
|
||||
useEffect(() => {
|
||||
if (
|
||||
hardware.myNodeNum !== 0 &&
|
||||
Object.keys(config).length === 7 &&
|
||||
Object.keys(moduleConfig).length === 7 &&
|
||||
channels.length === hardware.maxChannels
|
||||
) {
|
||||
setReady(true);
|
||||
}
|
||||
}, [
|
||||
config,
|
||||
moduleConfig,
|
||||
channels,
|
||||
hardware.maxChannels,
|
||||
hardware.myNodeNum,
|
||||
setReady
|
||||
]);
|
||||
|
||||
return (
|
||||
<Card className="flex-col">
|
||||
<Dropdown
|
||||
title="Config Status"
|
||||
icon={<AdjustmentsHorizontalIcon className="h-4" />}
|
||||
>
|
||||
<div className="flex flex-col gap-2 p-3">
|
||||
<ol className="flex flex-col gap-3 overflow-hidden">
|
||||
<StatusIndicator
|
||||
title="Device Info"
|
||||
current={hardware.myNodeNum ? 1 : 0}
|
||||
total={0}
|
||||
/>
|
||||
<StatusIndicator title="Peers" current={nodes.length} total={0} />
|
||||
<StatusIndicator
|
||||
title="Device Config"
|
||||
current={Object.keys(config).length - 1}
|
||||
total={6}
|
||||
/>
|
||||
<StatusIndicator
|
||||
title="Module Config"
|
||||
current={Object.keys(moduleConfig).length - 1}
|
||||
total={6}
|
||||
/>
|
||||
<StatusIndicator
|
||||
title="Channels"
|
||||
current={channels.length}
|
||||
total={hardware.maxChannels ?? 0}
|
||||
/>
|
||||
</ol>
|
||||
</div>
|
||||
</Dropdown>
|
||||
</Card>
|
||||
);
|
||||
};
|
||||
|
||||
export interface StatusIndicatorProps {
|
||||
title: string;
|
||||
current: number;
|
||||
total: number;
|
||||
}
|
||||
|
||||
const StatusIndicator = ({
|
||||
title,
|
||||
current,
|
||||
total
|
||||
}: StatusIndicatorProps): JSX.Element => {
|
||||
return (
|
||||
<li className="relative">
|
||||
<div
|
||||
className={`absolute top-4 left-2.5 -ml-px h-full w-0.5 ${
|
||||
current >= total ? "bg-green-500" : "bg-[#f9e3aa]"
|
||||
}`}
|
||||
/>
|
||||
<div className="flex">
|
||||
<div
|
||||
className={`relative z-10 flex h-5 w-5 rounded-full border-2 ${
|
||||
current === 0
|
||||
? "border-[#dabb6b] bg-[#f9e3aa]"
|
||||
: current >= total
|
||||
? "border-green-500 bg-green-500"
|
||||
: "border-green-500 bg-[#f9e3aa]"
|
||||
}`}
|
||||
>
|
||||
<span
|
||||
className={`m-auto h-1.5 w-1.5 rounded-full ${
|
||||
current > 0 ? "bg-green-500" : "bg-[#f9e3aa]"
|
||||
}`}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<span className="ml-4 flex gap-1 text-sm">
|
||||
<span className="font-medium">{title}</span>
|
||||
<span className="font-mono text-slate-500">
|
||||
({current}
|
||||
{total !== 0 && `/${total}`})
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
</li>
|
||||
);
|
||||
};
|
||||
@@ -1,11 +1,9 @@
|
||||
import type React from "react";
|
||||
|
||||
import { Button } from "@components/form/Button.js";
|
||||
import { Hashicon } from "@emeraldpay/hashicon-react";
|
||||
import { XCircleIcon } from "@heroicons/react/24/outline";
|
||||
|
||||
import { Button } from "../Button.js";
|
||||
import { Card } from "../Card.js";
|
||||
|
||||
export interface DeviceWidgetProps {
|
||||
name: string;
|
||||
nodeNum: string;
|
||||
@@ -22,7 +20,7 @@ export const DeviceWidget = ({
|
||||
reconnect
|
||||
}: DeviceWidgetProps): JSX.Element => {
|
||||
return (
|
||||
<Card className="relative shrink-0 flex-col">
|
||||
<div className="relative flex shrink-0 flex-col overflow-hidden rounded-md bg-white text-sm text-black shadow-md">
|
||||
<div className="absolute bottom-20 h-full w-full">
|
||||
<Hashicon size={350} value={nodeNum} />
|
||||
</div>
|
||||
@@ -46,6 +44,6 @@ export const DeviceWidget = ({
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Card>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,42 +0,0 @@
|
||||
import type React from "react";
|
||||
|
||||
import { InformationCircleIcon } from "@heroicons/react/24/outline";
|
||||
import type { Protobuf } from "@meshtastic/meshtasticjs";
|
||||
|
||||
import { Card } from "../Card.js";
|
||||
import { Dropdown } from "../Dropdown.js";
|
||||
|
||||
export interface NodeInfoWidgetProps {
|
||||
hardware: Protobuf.MyNodeInfo;
|
||||
}
|
||||
|
||||
export const NodeInfoWidget = ({
|
||||
hardware
|
||||
}: NodeInfoWidgetProps): JSX.Element => {
|
||||
return (
|
||||
<Card className="flex-col">
|
||||
<Dropdown
|
||||
title="Information"
|
||||
icon={<InformationCircleIcon className="h-4" />}
|
||||
>
|
||||
<div className="flex flex-col gap-2 p-3">
|
||||
<dl className="mt-2 border-b border-gray-200">
|
||||
<div className="flex justify-between py-1 text-sm font-medium">
|
||||
<dt className="text-gray-500">Firmware version</dt>
|
||||
<dd className="cursor-pointer whitespace-nowrap text-gray-900 hover:text-orange-400 hover:underline">
|
||||
{hardware.firmwareVersion}
|
||||
</dd>
|
||||
</div>
|
||||
</dl>
|
||||
<div className="flex justify-between py-1 text-sm font-medium">
|
||||
<dt className="text-gray-500">Bitrate</dt>
|
||||
<dd className="whitespace-nowrap text-gray-900">
|
||||
{hardware.bitrate.toFixed(2)}
|
||||
<span className="font-mono text-sm text-slate-500 ">bps</span>
|
||||
</dd>
|
||||
</div>
|
||||
</div>
|
||||
</Dropdown>
|
||||
</Card>
|
||||
);
|
||||
};
|
||||
@@ -1,15 +1,14 @@
|
||||
import type React from "react";
|
||||
|
||||
import { useDevice } from "@app/core/providers/useDevice.js";
|
||||
import { IconButton } from "@components/form/IconButton.js";
|
||||
import { Mono } from "@components/generic/Mono.js";
|
||||
import {
|
||||
EllipsisHorizontalIcon,
|
||||
UserGroupIcon
|
||||
} from "@heroicons/react/24/outline";
|
||||
import type { Protobuf } from "@meshtastic/meshtasticjs";
|
||||
|
||||
import { IconButton } from "../IconButton.js";
|
||||
import { Mono } from "../Mono.js";
|
||||
|
||||
export interface PeersWidgetProps {
|
||||
peers: Protobuf.NodeInfo[];
|
||||
}
|
||||
|
||||
@@ -5,11 +5,10 @@ import {
|
||||
bitwiseEncode,
|
||||
enumLike
|
||||
} from "@app/core/utils/bitwise.js";
|
||||
import { InfoWrapper } from "@components/form/InfoWrapper.js";
|
||||
import { Listbox } from "@headlessui/react";
|
||||
import { Protobuf } from "@meshtastic/meshtasticjs";
|
||||
|
||||
import { InfoWrapper } from "./InfoWrapper.js";
|
||||
|
||||
export interface BitwiseSelectProps {
|
||||
label?: string;
|
||||
description?: string;
|
||||
|
||||
@@ -3,7 +3,7 @@ import type { HTMLProps } from "react";
|
||||
|
||||
import { FiSave } from "react-icons/fi";
|
||||
|
||||
import { Button } from "@components/Button.js";
|
||||
import { Button } from "@components/form/Button.js";
|
||||
import {
|
||||
ArrowUturnLeftIcon,
|
||||
ChevronRightIcon,
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
import type React from "react";
|
||||
import { forwardRef, InputHTMLAttributes } from "react";
|
||||
|
||||
import { InfoWrapper, InfoWrapperProps } from "@components/form/InfoWrapper.js";
|
||||
import { ExclamationCircleIcon } from "@heroicons/react/24/outline";
|
||||
|
||||
import { InfoWrapper, InfoWrapperProps } from "./InfoWrapper.js";
|
||||
|
||||
export interface InputProps
|
||||
extends InputHTMLAttributes<HTMLInputElement>,
|
||||
Omit<InfoWrapperProps, "children"> {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import type React from "react";
|
||||
import { forwardRef, SelectHTMLAttributes } from "react";
|
||||
|
||||
import { InfoWrapper, InfoWrapperProps } from "./InfoWrapper.js";
|
||||
import { InfoWrapper, InfoWrapperProps } from "@components/form/InfoWrapper.js";
|
||||
|
||||
export interface SelectProps
|
||||
extends SelectHTMLAttributes<HTMLSelectElement>,
|
||||
|
||||
+9
-11
@@ -1,7 +1,7 @@
|
||||
import type React from "react";
|
||||
import { Fragment } from "react";
|
||||
|
||||
import { Mono } from "@app/components/Mono";
|
||||
import { Mono } from "@components/generic/Mono";
|
||||
import { Tab } from "@headlessui/react";
|
||||
|
||||
export interface TabType {
|
||||
@@ -29,10 +29,11 @@ export const TabbedContent = ({
|
||||
<Tab key={index}>
|
||||
{({ selected }) => (
|
||||
<div
|
||||
className={`flex h-10 cursor-pointer gap-3 rounded-md px-3 text-sm font-medium ${selected
|
||||
? "bg-gray-100 text-gray-700"
|
||||
: "text-gray-500 hover:text-gray-700"
|
||||
}
|
||||
className={`flex h-10 cursor-pointer gap-3 rounded-md px-3 text-sm font-medium ${
|
||||
selected
|
||||
? "bg-gray-100 text-gray-700"
|
||||
: "text-gray-500 hover:text-gray-700"
|
||||
}
|
||||
`}
|
||||
>
|
||||
{entry.icon && (
|
||||
@@ -57,12 +58,10 @@ export const TabbedContent = ({
|
||||
) : (
|
||||
<div>
|
||||
<Mono>
|
||||
{entry.disabledMessage || "This tab is disabled"}.
|
||||
{' '}
|
||||
{entry.disabledMessage || "This tab is disabled"}.{" "}
|
||||
{entry.disabledLink && (
|
||||
<>
|
||||
Click
|
||||
{' '}
|
||||
Click{" "}
|
||||
<a
|
||||
className="underline"
|
||||
target="_blank"
|
||||
@@ -70,8 +69,7 @@ export const TabbedContent = ({
|
||||
href={entry.disabledLink}
|
||||
>
|
||||
here
|
||||
</a>
|
||||
{' '}
|
||||
</a>{" "}
|
||||
for more information.
|
||||
</>
|
||||
)}
|
||||
Reference in New Issue
Block a user