mirror of https://github.com/jetkvm/kvm.git
More linting fixes
This commit is contained in:
parent
396f7f348d
commit
9979bb4161
|
@ -13,8 +13,8 @@
|
|||
"build:device": "tsc && vite build --mode=device --emptyOutDir",
|
||||
"build:staging": "tsc && vite build --mode=cloud-staging",
|
||||
"build:prod": "tsc && vite build --mode=cloud-production",
|
||||
"lint": "eslint ./src/**/*.{ts,tsx} --no-error-on-unmatched-pattern",
|
||||
"lint:fix": "eslint ./src/**/*.{ts,tsx} --no-error-on-unmatched-pattern --fix",
|
||||
"lint": "eslint './src/**/*.{ts,tsx}'",
|
||||
"lint:fix": "eslint './src/**/*.{ts,tsx}' --fix",
|
||||
"preview": "vite preview"
|
||||
},
|
||||
"dependencies": {
|
||||
|
|
|
@ -16,12 +16,9 @@ import Container from "@components/Container";
|
|||
import { cx } from "@/cva.config";
|
||||
import PasteModal from "@/components/popovers/PasteModal";
|
||||
import WakeOnLanModal from "@/components/popovers/WakeOnLan/Index";
|
||||
|
||||
|
||||
import { useDeviceUiNavigation } from "../hooks/useAppNavigation";
|
||||
|
||||
import MountPopopover from "./popovers/MountPopover";
|
||||
import ExtensionPopover from "./popovers/ExtensionPopover";
|
||||
import MountPopopover from "@/components/popovers/MountPopover";
|
||||
import ExtensionPopover from "@/components/popovers/ExtensionPopover";
|
||||
import { useDeviceUiNavigation } from "@/hooks/useAppNavigation";
|
||||
|
||||
export default function Actionbar({
|
||||
requestFullscreen,
|
||||
|
|
|
@ -47,8 +47,8 @@ export default function AuthLayout({
|
|||
}
|
||||
/>
|
||||
<Container>
|
||||
<div className="flex items-center justify-center w-full h-full isolate">
|
||||
<div className="max-w-2xl -mt-16 space-y-8">
|
||||
<div className="isolate flex h-full w-full items-center justify-center">
|
||||
<div className="-mt-16 max-w-2xl space-y-8">
|
||||
{showCounter ? (
|
||||
<div className="text-center">
|
||||
<StepCounter currStepIdx={0} nSteps={2} />
|
||||
|
@ -62,11 +62,8 @@ export default function AuthLayout({
|
|||
</div>
|
||||
|
||||
<Fieldset className="space-y-12">
|
||||
<div className="max-w-sm mx-auto space-y-4">
|
||||
<form
|
||||
action={`${CLOUD_API}/oidc/google`}
|
||||
method="POST"
|
||||
>
|
||||
<div className="mx-auto max-w-sm space-y-4">
|
||||
<form action={`${CLOUD_API}/oidc/google`} method="POST">
|
||||
{/*This could be the KVM ID*/}
|
||||
{deviceId ? (
|
||||
<input type="hidden" name="deviceId" value={deviceId} />
|
||||
|
|
|
@ -1,11 +1,13 @@
|
|||
import { Button } from "@components/Button";
|
||||
import { LuHardDrive, LuPower, LuRotateCcw } from "react-icons/lu";
|
||||
import { useEffect, useState } from "react";
|
||||
|
||||
import { Button } from "@components/Button";
|
||||
import Card from "@components/Card";
|
||||
import { SettingsPageHeader } from "@components/SettingsPageheader";
|
||||
import { useEffect, useState } from "react";
|
||||
import notifications from "@/notifications";
|
||||
import LoadingSpinner from "@/components/LoadingSpinner";
|
||||
|
||||
import { useJsonRpc } from "../../hooks/useJsonRpc";
|
||||
import LoadingSpinner from "../LoadingSpinner";
|
||||
|
||||
const LONG_PRESS_DURATION = 3000; // 3 seconds for long press
|
||||
|
||||
|
@ -102,11 +104,11 @@ export function ATXPowerControl() {
|
|||
|
||||
{atxState === null ? (
|
||||
<Card className="flex h-[120px] items-center justify-center p-3">
|
||||
<LoadingSpinner className="w-6 h-6 text-blue-500 dark:text-blue-400" />
|
||||
<LoadingSpinner className="h-6 w-6 text-blue-500 dark:text-blue-400" />
|
||||
</Card>
|
||||
) : (
|
||||
<Card className="h-[120px] animate-fadeIn opacity-0">
|
||||
<div className="p-3 space-y-4">
|
||||
<div className="space-y-4 p-3">
|
||||
{/* Control Buttons */}
|
||||
<div className="flex items-center space-x-2">
|
||||
<Button
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
import { Button } from "@components/Button";
|
||||
import { LuPower } from "react-icons/lu";
|
||||
import { useCallback, useEffect, useState } from "react";
|
||||
|
||||
import { Button } from "@components/Button";
|
||||
import Card from "@components/Card";
|
||||
import { SettingsPageHeader } from "@components/SettingsPageheader";
|
||||
import FieldLabel from "../FieldLabel";
|
||||
import { useJsonRpc } from "@/hooks/useJsonRpc";
|
||||
import { useCallback, useEffect, useState } from "react";
|
||||
import notifications from "@/notifications";
|
||||
import LoadingSpinner from "../LoadingSpinner";
|
||||
import FieldLabel from "@components/FieldLabel";
|
||||
import LoadingSpinner from "@components/LoadingSpinner";
|
||||
|
||||
interface DCPowerState {
|
||||
isOn: boolean;
|
||||
|
@ -59,11 +60,11 @@ export function DCPowerControl() {
|
|||
|
||||
{powerState === null ? (
|
||||
<Card className="flex h-[160px] justify-center p-3">
|
||||
<LoadingSpinner className="w-6 h-6 text-blue-500 dark:text-blue-400" />
|
||||
<LoadingSpinner className="h-6 w-6 text-blue-500 dark:text-blue-400" />
|
||||
</Card>
|
||||
) : (
|
||||
<Card className="h-[160px] animate-fadeIn opacity-0">
|
||||
<div className="p-3 space-y-4">
|
||||
<div className="space-y-4 p-3">
|
||||
{/* Power Controls */}
|
||||
<div className="flex items-center space-x-2">
|
||||
<Button
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
import { Button } from "@components/Button";
|
||||
import { LuTerminal } from "react-icons/lu";
|
||||
import { useEffect, useState } from "react";
|
||||
|
||||
import { Button } from "@components/Button";
|
||||
import Card from "@components/Card";
|
||||
import { SettingsPageHeader } from "@components/SettingsPageheader";
|
||||
import { SelectMenuBasic } from "../SelectMenuBasic";
|
||||
import { useJsonRpc } from "@/hooks/useJsonRpc";
|
||||
import { useEffect, useState } from "react";
|
||||
import notifications from "@/notifications";
|
||||
import { useUiStore } from "@/hooks/stores";
|
||||
import { SelectMenuBasic } from "@components/SelectMenuBasic";
|
||||
|
||||
interface SerialSettings {
|
||||
baudRate: string;
|
||||
|
|
|
@ -1,19 +1,20 @@
|
|||
import { useEffect, useState } from "react";
|
||||
import { LuPower, LuTerminal, LuPlugZap } from "react-icons/lu";
|
||||
|
||||
import { useJsonRpc } from "@/hooks/useJsonRpc";
|
||||
import Card, { GridCard } from "@components/Card";
|
||||
import { SettingsPageHeader } from "@components/SettingsPageheader";
|
||||
import { Button } from "../Button";
|
||||
import { LuPower, LuTerminal, LuPlugZap } from "react-icons/lu";
|
||||
import { ATXPowerControl } from "@components/extensions/ATXPowerControl";
|
||||
import { DCPowerControl } from "@components/extensions/DCPowerControl";
|
||||
import { SerialConsole } from "@components/extensions/SerialConsole";
|
||||
import notifications from "../../notifications";
|
||||
import { Button } from "@components/Button";
|
||||
import notifications from "@/notifications";
|
||||
|
||||
interface Extension {
|
||||
id: string;
|
||||
name: string;
|
||||
description: string;
|
||||
icon: any;
|
||||
icon: React.ElementType;
|
||||
}
|
||||
|
||||
const AVAILABLE_EXTENSIONS: Extension[] = [
|
||||
|
@ -58,7 +59,9 @@ export default function ExtensionPopover() {
|
|||
const handleSetActiveExtension = (extension: Extension | null) => {
|
||||
send("setActiveExtension", { extensionId: extension?.id || "" }, resp => {
|
||||
if ("error" in resp) {
|
||||
notifications.error(`Failed to set active extension: ${resp.error.data || "Unknown error"}`);
|
||||
notifications.error(
|
||||
`Failed to set active extension: ${resp.error.data || "Unknown error"}`,
|
||||
);
|
||||
return;
|
||||
}
|
||||
setActiveExtension(extension);
|
||||
|
@ -80,7 +83,7 @@ export default function ExtensionPopover() {
|
|||
|
||||
return (
|
||||
<GridCard>
|
||||
<div className="p-4 py-3 space-y-4">
|
||||
<div className="space-y-4 p-4 py-3">
|
||||
<div className="grid h-full grid-rows-headerBody">
|
||||
<div className="space-y-4">
|
||||
{activeExtension ? (
|
||||
|
@ -89,7 +92,7 @@ export default function ExtensionPopover() {
|
|||
{renderActiveExtension()}
|
||||
|
||||
<div
|
||||
className="flex items-center justify-end space-x-2 opacity-0 animate-fadeIn"
|
||||
className="flex animate-fadeIn items-center justify-end space-x-2 opacity-0"
|
||||
style={{
|
||||
animationDuration: "0.7s",
|
||||
animationDelay: "0.2s",
|
||||
|
@ -110,7 +113,7 @@ export default function ExtensionPopover() {
|
|||
title="Extensions"
|
||||
description="Load and manage your extensions"
|
||||
/>
|
||||
<Card className="opacity-0 animate-fadeIn">
|
||||
<Card className="animate-fadeIn opacity-0">
|
||||
<div className="w-full divide-y divide-slate-700/30 dark:divide-slate-600/30">
|
||||
{AVAILABLE_EXTENSIONS.map(extension => (
|
||||
<div
|
||||
|
|
|
@ -1,11 +1,6 @@
|
|||
import { Button } from "@components/Button";
|
||||
import { ExclamationTriangleIcon } from "@heroicons/react/24/outline";
|
||||
import Card, { GridCard } from "@components/Card";
|
||||
import { PlusCircleIcon } from "@heroicons/react/20/solid";
|
||||
import { useMemo, forwardRef, useEffect, useCallback } from "react";
|
||||
import { formatters } from "@/utils";
|
||||
import { RemoteVirtualMediaState, useMountMediaStore, useRTCStore } from "@/hooks/stores";
|
||||
import { SettingsPageHeader } from "@components/SettingsPageheader";
|
||||
import {
|
||||
LuArrowUpFromLine,
|
||||
LuCheckCheck,
|
||||
|
@ -13,11 +8,17 @@ import {
|
|||
LuPlus,
|
||||
LuRadioReceiver,
|
||||
} from "react-icons/lu";
|
||||
import { useJsonRpc } from "@/hooks/useJsonRpc";
|
||||
import notifications from "../../notifications";
|
||||
import { useClose } from "@headlessui/react";
|
||||
import { useLocation } from "react-router-dom";
|
||||
|
||||
import { Button } from "@components/Button";
|
||||
import Card, { GridCard } from "@components/Card";
|
||||
import { formatters } from "@/utils";
|
||||
import { RemoteVirtualMediaState, useMountMediaStore, useRTCStore } from "@/hooks/stores";
|
||||
import { SettingsPageHeader } from "@components/SettingsPageheader";
|
||||
import { useJsonRpc } from "@/hooks/useJsonRpc";
|
||||
import { useDeviceUiNavigation } from "@/hooks/useAppNavigation";
|
||||
import notifications from "@/notifications";
|
||||
|
||||
const MountPopopover = forwardRef<HTMLDivElement, object>((_props, ref) => {
|
||||
const diskDataChannelStats = useRTCStore(state => state.diskDataChannelStats);
|
||||
|
|
|
@ -1,15 +1,16 @@
|
|||
import { useCallback, useEffect, useRef, useState } from "react";
|
||||
import { LuCornerDownLeft } from "react-icons/lu";
|
||||
import { ExclamationCircleIcon } from "@heroicons/react/16/solid";
|
||||
import { useClose } from "@headlessui/react";
|
||||
|
||||
import { Button } from "@components/Button";
|
||||
import { GridCard } from "@components/Card";
|
||||
import { TextAreaWithLabel } from "@components/TextArea";
|
||||
import { SettingsPageHeader } from "@components/SettingsPageheader";
|
||||
import { useJsonRpc } from "@/hooks/useJsonRpc";
|
||||
import { useHidStore, useRTCStore, useUiStore } from "@/hooks/stores";
|
||||
import notifications from "../../notifications";
|
||||
import { useCallback, useEffect, useRef, useState } from "react";
|
||||
import { LuCornerDownLeft } from "react-icons/lu";
|
||||
import { ExclamationCircleIcon } from "@heroicons/react/16/solid";
|
||||
import { useClose } from "@headlessui/react";
|
||||
import { chars, keys, modifiers } from "@/keyboardMappings";
|
||||
import notifications from "@/notifications";
|
||||
|
||||
const hidKeyboardPayload = (keys: number[], modifier: number) => {
|
||||
return { keys, modifier };
|
||||
|
@ -59,6 +60,7 @@ export default function PasteModal() {
|
|||
});
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
notifications.error("Failed to paste text");
|
||||
}
|
||||
}, [rpcDataChannel?.readyState, send, setDisableVideoFocusTrap, setPasteMode]);
|
||||
|
@ -71,7 +73,7 @@ export default function PasteModal() {
|
|||
|
||||
return (
|
||||
<GridCard>
|
||||
<div className="p-4 py-3 space-y-4">
|
||||
<div className="space-y-4 p-4 py-3">
|
||||
<div className="grid h-full grid-rows-headerBody">
|
||||
<div className="h-full space-y-4">
|
||||
<div className="space-y-4">
|
||||
|
@ -81,7 +83,7 @@ export default function PasteModal() {
|
|||
/>
|
||||
|
||||
<div
|
||||
className="space-y-2 opacity-0 animate-fadeIn"
|
||||
className="animate-fadeIn space-y-2 opacity-0"
|
||||
style={{
|
||||
animationDuration: "0.7s",
|
||||
animationDelay: "0.1s",
|
||||
|
@ -120,8 +122,8 @@ export default function PasteModal() {
|
|||
/>
|
||||
|
||||
{invalidChars.length > 0 && (
|
||||
<div className="flex items-center mt-2 gap-x-2">
|
||||
<ExclamationCircleIcon className="w-4 h-4 text-red-500 dark:text-red-400" />
|
||||
<div className="mt-2 flex items-center gap-x-2">
|
||||
<ExclamationCircleIcon className="h-4 w-4 text-red-500 dark:text-red-400" />
|
||||
<span className="text-xs text-red-500 dark:text-red-400">
|
||||
The following characters won't be pasted:{" "}
|
||||
{invalidChars.join(", ")}
|
||||
|
@ -135,7 +137,7 @@ export default function PasteModal() {
|
|||
</div>
|
||||
</div>
|
||||
<div
|
||||
className="flex items-center justify-end opacity-0 animate-fadeIn gap-x-2"
|
||||
className="flex animate-fadeIn items-center justify-end gap-x-2 opacity-0"
|
||||
style={{
|
||||
animationDuration: "0.7s",
|
||||
animationDelay: "0.2s",
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import { InputFieldWithLabel } from "@components/InputField";
|
||||
import { useState, useRef } from "react";
|
||||
import { LuPlus } from "react-icons/lu";
|
||||
import { Button } from "../../Button";
|
||||
import { LuArrowLeft } from "react-icons/lu";
|
||||
import { LuPlus, LuArrowLeft } from "react-icons/lu";
|
||||
|
||||
import { InputFieldWithLabel } from "@/components/InputField";
|
||||
import { Button } from "@/components/Button";
|
||||
|
||||
interface AddDeviceFormProps {
|
||||
onAddDevice: (name: string, macAddress: string) => void;
|
||||
|
@ -26,7 +26,7 @@ export default function AddDeviceForm({
|
|||
return (
|
||||
<div className="space-y-4">
|
||||
<div
|
||||
className="space-y-4 opacity-0 animate-fadeIn"
|
||||
className="animate-fadeIn space-y-4 opacity-0"
|
||||
style={{
|
||||
animationDuration: "0.5s",
|
||||
animationFillMode: "forwards",
|
||||
|
@ -73,7 +73,7 @@ export default function AddDeviceForm({
|
|||
/>
|
||||
</div>
|
||||
<div
|
||||
className="flex items-center justify-end space-x-2 opacity-0 animate-fadeIn"
|
||||
className="flex animate-fadeIn items-center justify-end space-x-2 opacity-0"
|
||||
style={{
|
||||
animationDuration: "0.7s",
|
||||
animationDelay: "0.2s",
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
import { Button } from "@components/Button";
|
||||
import Card from "@components/Card";
|
||||
import { FieldError } from "@components/InputField";
|
||||
import { LuPlus, LuSend, LuTrash2 } from "react-icons/lu";
|
||||
|
||||
import { Button } from "@/components/Button";
|
||||
import Card from "@/components/Card";
|
||||
import { FieldError } from "@/components/InputField";
|
||||
|
||||
export interface StoredDevice {
|
||||
name: string;
|
||||
macAddress: string;
|
||||
|
@ -27,12 +28,14 @@ export default function DeviceList({
|
|||
}: DeviceListProps) {
|
||||
return (
|
||||
<div className="space-y-4">
|
||||
<Card className="opacity-0 animate-fadeIn">
|
||||
<Card className="animate-fadeIn opacity-0">
|
||||
<div className="w-full divide-y divide-slate-700/30 dark:divide-slate-600/30">
|
||||
{storedDevices.map((device, index) => (
|
||||
<div key={index} className="flex items-center justify-between p-3 gap-x-2">
|
||||
<div key={index} className="flex items-center justify-between gap-x-2 p-3">
|
||||
<div className="space-y-0.5">
|
||||
<p className="text-sm font-semibold leading-none text-slate-900 dark:text-slate-100">{device?.name}</p>
|
||||
<p className="text-sm font-semibold leading-none text-slate-900 dark:text-slate-100">
|
||||
{device?.name}
|
||||
</p>
|
||||
<p className="text-sm text-slate-600 dark:text-slate-400">
|
||||
{device.macAddress?.toLowerCase()}
|
||||
</p>
|
||||
|
@ -60,18 +63,13 @@ export default function DeviceList({
|
|||
</div>
|
||||
</Card>
|
||||
<div
|
||||
className="flex items-center justify-end space-x-2 opacity-0 animate-fadeIn"
|
||||
className="flex animate-fadeIn items-center justify-end space-x-2 opacity-0"
|
||||
style={{
|
||||
animationDuration: "0.7s",
|
||||
animationDelay: "0.2s",
|
||||
}}
|
||||
>
|
||||
<Button
|
||||
size="SM"
|
||||
theme="blank"
|
||||
text="Close"
|
||||
onClick={onCancelWakeOnLanModal}
|
||||
/>
|
||||
<Button size="SM" theme="blank" text="Close" onClick={onCancelWakeOnLanModal} />
|
||||
<Button
|
||||
size="SM"
|
||||
theme="primary"
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
import Card from "@components/Card";
|
||||
import { PlusCircleIcon } from "@heroicons/react/16/solid";
|
||||
import { LuPlus } from "react-icons/lu";
|
||||
import { Button } from "../../Button";
|
||||
|
||||
import Card from "@/components/Card";
|
||||
import { Button } from "@/components/Button";
|
||||
|
||||
export default function EmptyStateCard({
|
||||
onCancelWakeOnLanModal,
|
||||
|
@ -11,15 +12,15 @@ export default function EmptyStateCard({
|
|||
setShowAddForm: (show: boolean) => void;
|
||||
}) {
|
||||
return (
|
||||
<div className="space-y-4 select-none">
|
||||
<Card className="opacity-0 animate-fadeIn">
|
||||
<div className="select-none space-y-4">
|
||||
<Card className="animate-fadeIn opacity-0">
|
||||
<div className="flex items-center justify-center py-8 text-center">
|
||||
<div className="space-y-3">
|
||||
<div className="space-y-1">
|
||||
<div className="inline-block">
|
||||
<Card>
|
||||
<div className="p-1">
|
||||
<PlusCircleIcon className="w-4 h-4 text-blue-700 shrink-0 dark:text-white" />
|
||||
<PlusCircleIcon className="h-4 w-4 shrink-0 text-blue-700 dark:text-white" />
|
||||
</div>
|
||||
</Card>
|
||||
</div>
|
||||
|
@ -34,7 +35,7 @@ export default function EmptyStateCard({
|
|||
</div>
|
||||
</Card>
|
||||
<div
|
||||
className="flex items-center justify-end space-x-2 opacity-0 animate-fadeIn"
|
||||
className="flex animate-fadeIn items-center justify-end space-x-2 opacity-0"
|
||||
style={{
|
||||
animationDuration: "0.7s",
|
||||
animationDelay: "0.2s",
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
import { useCallback, useEffect, useState } from "react";
|
||||
import { useClose } from "@headlessui/react";
|
||||
|
||||
import { GridCard } from "@components/Card";
|
||||
import { SettingsPageHeader } from "@components/SettingsPageheader";
|
||||
import { useJsonRpc } from "@/hooks/useJsonRpc";
|
||||
import { useRTCStore, useUiStore } from "@/hooks/stores";
|
||||
import notifications from "@/notifications";
|
||||
import { useCallback, useEffect, useState } from "react";
|
||||
import { useClose } from "@headlessui/react";
|
||||
|
||||
import EmptyStateCard from "./EmptyStateCard";
|
||||
import DeviceList, { StoredDevice } from "./DeviceList";
|
||||
import AddDeviceForm from "./AddDeviceForm";
|
||||
|
@ -99,7 +101,7 @@ export default function WakeOnLanModal() {
|
|||
|
||||
return (
|
||||
<GridCard>
|
||||
<div className="p-4 py-3 space-y-4">
|
||||
<div className="space-y-4 p-4 py-3">
|
||||
<div className="grid h-full grid-rows-headerBody">
|
||||
<div className="space-y-4">
|
||||
<SettingsPageHeader
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
import SidebarHeader from "@components/SidebarHeader";
|
||||
import { GridCard } from "@components/Card";
|
||||
import { useRTCStore, useUiStore } from "@/hooks/stores";
|
||||
import StatChart from "@components/StatChart";
|
||||
import { useInterval } from "usehooks-ts";
|
||||
|
||||
import SidebarHeader from "@/components/SidebarHeader";
|
||||
import { GridCard } from "@/components/Card";
|
||||
import { useRTCStore, useUiStore } from "@/hooks/stores";
|
||||
import StatChart from "@/components/StatChart";
|
||||
|
||||
function createChartArray<T, K extends keyof T>(
|
||||
stream: Map<number, T>,
|
||||
metric: K,
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
import toast, { Toast, Toaster, useToasterStore } from "react-hot-toast";
|
||||
import React, { useEffect } from "react";
|
||||
import { CheckCircleIcon, XCircleIcon } from "@heroicons/react/20/solid";
|
||||
|
||||
import Card from "@/components/Card";
|
||||
|
||||
import { CheckCircleIcon, XCircleIcon } from "@heroicons/react/20/solid";
|
||||
|
||||
interface NotificationOptions {
|
||||
duration?: number;
|
||||
|
|
|
@ -2,19 +2,18 @@ import { useLoaderData, useNavigate } from "react-router-dom";
|
|||
import { ShieldCheckIcon } from "@heroicons/react/24/outline";
|
||||
import { useCallback, useEffect, useState } from "react";
|
||||
|
||||
import api from "@/api";
|
||||
import { SettingsPageHeader } from "@components/SettingsPageheader";
|
||||
|
||||
import { useDeviceUiNavigation } from "../hooks/useAppNavigation";
|
||||
import { GridCard } from "../components/Card";
|
||||
import notifications from "../notifications";
|
||||
import api from "../api";
|
||||
import { DEVICE_API } from "../ui.config";
|
||||
import { Button, LinkButton } from "../components/Button";
|
||||
import { useJsonRpc } from "../hooks/useJsonRpc";
|
||||
import { InputFieldWithLabel } from "../components/InputField";
|
||||
import { SelectMenuBasic } from "../components/SelectMenuBasic";
|
||||
import { SettingsSectionHeader } from "../components/SettingsSectionHeader";
|
||||
import { isOnDevice } from "../main";
|
||||
import { GridCard } from "@/components/Card";
|
||||
import { Button, LinkButton } from "@/components/Button";
|
||||
import { InputFieldWithLabel } from "@/components/InputField";
|
||||
import { SelectMenuBasic } from "@/components/SelectMenuBasic";
|
||||
import { SettingsSectionHeader } from "@/components/SettingsSectionHeader";
|
||||
import { useDeviceUiNavigation } from "@/hooks/useAppNavigation";
|
||||
import notifications from "@/notifications";
|
||||
import { DEVICE_API } from "@/ui.config";
|
||||
import { useJsonRpc } from "@/hooks/useJsonRpc";
|
||||
import { isOnDevice } from "@/main";
|
||||
|
||||
import { LocalDevice } from "./devices.$id";
|
||||
import { SettingsItem } from "./devices.$id.settings";
|
||||
|
|
|
@ -51,8 +51,8 @@ export const formatters = {
|
|||
];
|
||||
|
||||
let duration = (date.valueOf() - new Date().valueOf()) / 1000;
|
||||
for (let i = 0; i < DIVISIONS.length; i++) {
|
||||
const division = DIVISIONS[i];
|
||||
|
||||
for (const division of DIVISIONS) {
|
||||
if (Math.abs(duration) < division.amount) {
|
||||
return relativeTimeFormat.format(Math.round(duration), division.name);
|
||||
}
|
||||
|
@ -61,7 +61,7 @@ export const formatters = {
|
|||
},
|
||||
|
||||
price: (price: number | bigint | string, options?: Intl.NumberFormatOptions) => {
|
||||
let opts: Intl.NumberFormatOptions = {
|
||||
const opts: Intl.NumberFormatOptions = {
|
||||
style: "currency",
|
||||
currency: "USD",
|
||||
...(options || {}),
|
||||
|
|
Loading…
Reference in New Issue