"use client" import { useEffect, useState, useMemo } from "react" import { useRouter } from "next/navigation" import { api } from "@/lib/api" import { Header } from "@/components/Header" import { Card, CardContent } from "@/components/ui/card" import { Button } from "@/components/ui/button" import { Badge } from "@/components/ui/badge" import { RefreshCw, X, Zap, Target, Wifi, Clock, FolderOpen } from "lucide-react" type Unit = { name: string active: string sub: string description: string } type UnitType = "services" | "targets" | "sockets" | "timers" | "paths" export default function Services() { const router = useRouter() const [units, setUnits] = useState>({ services: [], targets: [], sockets: [], timers: [], paths: [], }) const [loading, setLoading] = useState(true) // Filter states const [activeTab, setActiveTab] = useState("services") const [searchText, setSearchText] = useState("") const [activeStatus, setActiveStatus] = useState("all") // all, active, inactive const [fileStatus, setFileStatus] = useState("all") // all, enabled, disabled, static useEffect(() => { const token = localStorage.getItem("access_token") if (!token) { router.push("/login") return } loadUnits() }, [router]) const loadUnits = async () => { setLoading(true) try { const data = await api.getUnits() setUnits(data) } catch (error) { console.error("Failed to load units:", error) setUnits({ services: [], targets: [], sockets: [], timers: [], paths: [], }) } finally { setLoading(false) } } // Filter current tab's units const filteredUnits = useMemo(() => { let filtered = units[activeTab] || [] // Search filter (name or description) if (searchText) { filtered = filtered.filter((unit) => { const searchLower = searchText.toLowerCase() return ( unit.name.toLowerCase().includes(searchLower) || unit.description.toLowerCase().includes(searchLower) ) }) } // Active status filter if (activeStatus === "active") { filtered = filtered.filter((unit) => unit.active === "active") } else if (activeStatus === "inactive") { filtered = filtered.filter((unit) => unit.active === "inactive") } // File status filter if (fileStatus !== "all") { filtered = filtered.filter((unit) => { const sub = unit.sub.toLowerCase() if (fileStatus === "enabled") { return sub === "enabled" } else if (fileStatus === "disabled") { return sub === "disabled" } else if (fileStatus === "static") { return sub === "static" } return true }) } return filtered }, [units, activeTab, searchText, activeStatus, fileStatus]) const tabConfig: Record< UnitType, { label: string; icon: React.ReactNode; count: number } > = { services: { label: "Dienste", icon: , count: units.services.length, }, targets: { label: "Ziele", icon: , count: units.targets.length, }, sockets: { label: "Sockets", icon: , count: units.sockets.length, }, timers: { label: "Timer", icon: , count: units.timers.length, }, paths: { label: "Pfade", icon: , count: units.paths.length, }, } const getStatusBadge = (status: string) => { if (status === "active") { return Aktiv } return Inaktiv } const getSubStatusBadge = (sub: string) => { const subLower = sub.toLowerCase() if (subLower === "running") { return Läuft } else if (subLower === "enabled") { return Aktiviert } else if (subLower === "disabled") { return Deaktiviert } else if (subLower === "static") { return Statisch } return {sub} } const hasActiveFilters = searchText || activeStatus !== "all" || fileStatus !== "all" return (

Systemd Einheiten

Dienste, Ziele, Sockets, Timer und Pfade

{/* Tabs */}
{(Object.keys(tabConfig) as UnitType[]).map((tab) => ( ))}
{/* Filter Section */}
{/* Search Filter */}
setSearchText(e.target.value)} className="w-full px-3 py-2 rounded-md border border-border bg-background text-sm" />
{/* Active Status Filter */}
{/* File Status Filter */}
{/* Active Filters Display */} {hasActiveFilters && (
Filter: {searchText && ( "{searchText}" )} {activeStatus !== "all" && ( {activeStatus === "active" ? "Aktiv" : "Inaktiv"} )} {fileStatus !== "all" && ( {fileStatus === "enabled" ? "Aktiviert" : fileStatus === "disabled" ? "Deaktiviert" : "Statisch"} )}
)}
{/* Units Table */}
{filteredUnits.length === 0 ? ( ) : ( filteredUnits.map((unit, idx) => ( )) )}
Name Aktiver Status Dateistatus Beschreibung
{loading ? "Lädt..." : "Keine Einheiten gefunden"}
{unit.name} {getStatusBadge(unit.active)} {getSubStatusBadge(unit.sub)} {unit.description || "—"}
Zeige {filteredUnits.length} von {units[activeTab]?.length || 0}{" "} {tabConfig[activeTab].label.toLowerCase()}
) }