IKHSAN
ENID Baca dalam Bahasa Indonesia

homeio

Public

Forked from doctor-io/homeio

Branch
main
Latest commit
958d74616 October 2026

updates-section.tsx

Open raw
"use client";

import {
  InfoBanner,
  SectionDivider,
  Toggle,
} from "@/modules/settings/components/panel/controls";
import {
  SETTINGS_PANEL_INSET,
} from "@/modules/settings/components/panel/surface";
import type { SettingsBackend } from "@/modules/settings/components/panel/types";
import { RefreshCw } from "@/components/icons/platform-icons";
import { cn } from "@/lib/utils";

type UpdatesSectionProps = {
  data: SettingsBackend["updates"];
  capabilities: SettingsBackend["capabilities"]["updates"];
  onCheckForUpdates: () => void;
  onApplyUpdate: () => void;
  autoCheckEnabled: boolean;
  onToggleAutoCheck: (enabled: boolean) => void;
};

export function UpdatesSection({
  data,
  capabilities,
  onCheckForUpdates,
  onApplyUpdate,
  autoCheckEnabled,
  onToggleAutoCheck,
}: UpdatesSectionProps) {
  const hasUpdate = data.updateAvailable && !!data.latestVersion;
  const lastCheckedLabel = data.checkedAt
    ? new Date(data.checkedAt).toLocaleString()
    : "Never";

  return (
    <div className="flex flex-col gap-1">
      {data.warning && (
        <InfoBanner text={data.warning} variant={data.unavailable ? "warning" : "info"} />
      )}
      {data.checkError && <InfoBanner text={data.checkError} variant="warning" />}
      {data.applyError && <InfoBanner text={data.applyError} variant="warning" />}
      {data.isRecoveryActive && (
        <InfoBanner
          text="Homeio is restarting to finish the update. This page will reconnect automatically."
          variant="info"
        />
      )}

      {/* ── Status card ── */}
      <SectionDivider title="Homeio" />
      <div className={cn(SETTINGS_PANEL_INSET, "overflow-hidden")}>
        {/* Header row */}
        <div className="flex items-center justify-between gap-3 px-4 py-3">
          <div className="flex items-center gap-2.5">
            <div className={cn(
              "size-2 rounded-full",
              hasUpdate ? "bg-status-amber" : "bg-status-green",
            )} />
            <span className="text-sm font-medium text-foreground">
              {hasUpdate ? `v${data.latestVersion} available` : "Up to date"}
            </span>
          </div>
          <div className="flex items-center gap-1.5">
            <button
              onClick={onCheckForUpdates}
              disabled={capabilities.checkForUpdates.disabled || data.isChecking || data.isRecoveryActive}
              className="inline-flex items-center gap-1.5 rounded-lg border border-glass-border bg-background/55 px-3 py-1.5 text-xs text-muted-foreground transition-colors hover:text-foreground disabled:cursor-not-allowed disabled:opacity-50"
            >
              <RefreshCw className={cn("size-3", data.isChecking && "animate-spin")} />
              {data.isChecking ? "Checking…" : "Check"}
            </button>
            {hasUpdate && (
              <button
                onClick={onApplyUpdate}
                disabled={capabilities.updateHomeio.disabled || data.isApplying || data.isRecoveryActive}
                className="inline-flex items-center gap-1.5 rounded-lg bg-primary/15 px-3 py-1.5 text-xs font-medium text-primary transition-colors hover:bg-primary/25 disabled:cursor-not-allowed disabled:opacity-50"
              >
                {data.isApplying || data.isRecoveryActive ? "Updating…" : "Update"}
              </button>
            )}
          </div>
        </div>

        {/* Version rows */}
        <div className="divide-y divide-glass-border/50 border-t border-glass-border/50 px-4">
          <div className="flex items-center justify-between py-2.5">
            <span className="text-xs text-muted-foreground">Current version</span>
            <span className="font-mono text-xs font-medium text-foreground">{data.currentVersion}</span>
          </div>
          <div className="flex items-center justify-between py-2.5">
            <span className="text-xs text-muted-foreground">Latest version</span>
            <span className="font-mono text-xs font-medium text-foreground">
              {data.latestVersion ?? "—"}
            </span>
          </div>
          <div className="flex items-center justify-between py-2.5">
            <span className="text-xs text-muted-foreground">Last checked</span>
            <span className="text-xs text-foreground">{lastCheckedLabel}</span>
          </div>
        </div>
      </div>

      {/* ── Preferences ── */}
      <SectionDivider title="Preferences" />
      <div className={cn(SETTINGS_PANEL_INSET, "px-4 py-1")}>
        <Toggle
          label="Auto-check for updates"
          description="Check for new updates daily"
          enabled={autoCheckEnabled}
          onToggle={() => onToggleAutoCheck(!autoCheckEnabled)}
          disabled={capabilities.autoCheck.disabled}
          disabledReason={capabilities.autoCheck.disabledReason}
        />
      </div>
    </div>
  );
}
bytes
4,909
lines
120
Type
tsx
Latest commit
16 October 2026