import { useState, useEffect, useCallback, lazy, Suspense } from "react";
import { invoke } from "@tauri-apps/api/core";
import type { UserDto, DbStatus, SafeDbInfo, ServerUserDto, UserProfileDto } from "../../types";
import logoUrl from "../../assets/logo.png";
import {
HomeNavIcon,
UsersNavIcon,
SettingsNavIcon,
HelpNavIcon,
LogOutIcon,
ChevronLeftIcon,
CinemaNavIcon,
MenuIcon,
CloseIcon,
} from "../../components/Icons";
import Home from "../home/Home";
import Users from "../users/Users";
import Settings from "../settings/Settings";
import Help from "../help/Help";
import Profile from "../profile/Profile";
import "./Dashboard.css";
const Cinema = lazy(() => import("../cinema/Cinema"));
function CinemaLoadingFallback() {
return (
);
}
interface DashboardProps {
user: UserDto;
dbInfo: SafeDbInfo | null;
dbStatus: DbStatus | null;
onLogout: () => void;
}
type NavTab = "cinema" | "home" | "users" | "settings" | "profile" | "help";
// Helper for Smart TV / Android TV detection
const detectTvEnvironment = (): boolean => {
if (typeof window === "undefined") return false;
const saved = localStorage.getItem("has_tv_mode");
if (saved !== null) return saved === "true";
const ua = (navigator.userAgent || "").toLowerCase();
const isTvUa =
ua.includes("android tv") ||
ua.includes("smarttv") ||
ua.includes("googletv") ||
ua.includes("tizen") ||
ua.includes("webos") ||
ua.includes("appletv") ||
ua.includes("crkey") ||
ua.includes("bravia") ||
ua.includes("aftt") ||
ua.includes("aftm") ||
ua.includes("mibox") ||
ua.includes("mi box") ||
ua.includes("shield") ||
ua.includes("dtv") ||
ua.includes("smart-tv") ||
ua.includes("hbbtv") ||
ua.includes("netcast") ||
ua.includes("viera") ||
ua.includes("roku") ||
ua.includes("firetv");
if (isTvUa) return true;
const isAndroid = ua.includes("android");
const noTouch = !("ontouchstart" in window) && navigator.maxTouchPoints === 0;
if (isAndroid && noTouch) return true;
return false;
};
export default function Dashboard({
user,
dbInfo,
dbStatus,
onLogout,
}: DashboardProps) {
const [currentUser, setCurrentUser] = useState(user);
useEffect(() => {
setCurrentUser(user);
}, [user]);
const [isTvEnvironment, setIsTvEnvironment] = useState(detectTvEnvironment);
const [activeTab, setActiveTab] = useState("cinema");
const [serverUsers, setServerUsers] = useState([]);
const [loadingUsers, setLoadingUsers] = useState(false);
const [isCollapsed, setIsCollapsed] = useState(() => {
return localStorage.getItem("has_sidebar_collapsed") === "true";
});
const [mobileMenuOpen, setMobileMenuOpen] = useState(false);
// Dynamic D-Pad Remote Control Key Listener (Auto-detects TV when user presses remote buttons)
useEffect(() => {
const handleRemoteDpadKey = (e: KeyboardEvent) => {
const isRemoteKey =
[19, 20, 21, 22, 23, 4, 82, 85, 179].includes(e.keyCode) ||
["ArrowUp", "ArrowDown", "ArrowLeft", "ArrowRight"].includes(e.key);
if (isRemoteKey && !isTvEnvironment) {
setIsTvEnvironment(true);
localStorage.setItem("has_tv_mode", "true");
}
};
window.addEventListener("keydown", handleRemoteDpadKey);
return () => window.removeEventListener("keydown", handleRemoteDpadKey);
}, [isTvEnvironment]);
const handleNavClick = (tab: NavTab) => {
setActiveTab(tab);
setMobileMenuOpen(false);
};
const toggleSidebar = () => {
setIsCollapsed((prev) => {
const next = !prev;
localStorage.setItem("has_sidebar_collapsed", String(next));
return next;
});
};
const displayName = currentUser.username?.trim() || currentUser.email.split("@")[0];
const isTauri = typeof window !== "undefined" && "__TAURI_INTERNALS__" in window;
useEffect(() => {
if (isTauri && currentUser.email) {
invoke("get_user_profile", { userEmail: currentUser.email })
.then((profile) => {
if (profile) {
setCurrentUser((prev) => ({
...prev,
username: profile.username || prev.username,
avatar: profile.avatar !== undefined ? profile.avatar : prev.avatar,
role: profile.role || prev.role,
}));
}
})
.catch((err) => {
console.warn("Could not preload user avatar for sidebar:", err);
});
}
}, [currentUser.email, isTauri]);
// Periodic heartbeat to keep user online status updated in database
useEffect(() => {
if (!isTauri || !currentUser.email) return;
const sendHeartbeat = () => {
invoke("update_user_heartbeat", { userEmail: currentUser.email }).catch(() => {});
};
sendHeartbeat();
const interval = setInterval(sendHeartbeat, 30000);
window.addEventListener("focus", sendHeartbeat);
return () => {
clearInterval(interval);
window.removeEventListener("focus", sendHeartbeat);
};
}, [currentUser.email, isTauri]);
const isUserAdmin =
(currentUser.role || "").toLowerCase() === "admin" ||
(currentUser.role || "").toLowerCase() === "администратор" ||
currentUser.email.toLowerCase() === "ne60201@gmail.com" ||
serverUsers.some(
(u) =>
u.email.toLowerCase() === currentUser.email.toLowerCase() &&
(u.role?.toLowerCase() === "admin" || u.role?.toLowerCase() === "администратор" || u.id === 1)
);
// Non-admin redirection: users and home (server stats) tabs are reserved for admin
useEffect(() => {
if (!isUserAdmin && (activeTab === "users" || activeTab === "home")) {
setActiveTab("cinema");
}
}, [isUserAdmin, activeTab]);
const isCinemaView = activeTab === "cinema";
const loadServerUsers = useCallback(async () => {
if (!isTauri) return;
setLoadingUsers(true);
try {
const res = await invoke("list_server_users");
if (Array.isArray(res)) {
setServerUsers(res);
}
} catch (err) {
console.error("Ошибка загрузки пользователей:", err);
} finally {
setLoadingUsers(false);
}
}, [isTauri]);
useEffect(() => {
loadServerUsers();
}, [loadServerUsers]);
useEffect(() => {
if (activeTab === "users") {
loadServerUsers();
}
}, [activeTab, loadServerUsers]);
return (
{/* Mobile Top Header (Visible on Mobile / Small screens) */}
{/* Backdrop for mobile drawer */}
{mobileMenuOpen && (
setMobileMenuOpen(false)}
/>
)}
{/* ========================================================
LEFT SIDEBAR NAVIGATION (Desktop Sidebar / Mobile Drawer)
======================================================== */}
{/* ========================================================
MAIN CONTENT VIEW AREA
======================================================== */}
{/* Top Header Row (Hidden on Profile and Cinema views) */}
{!isCinemaView && activeTab !== "profile" && (
)}
{/* Content Body Rendering Separate Page Components */}
{activeTab === "cinema" && (
}>
handleNavClick(tab as NavTab)}
onLogout={onLogout}
isTvEnvironment={isTvEnvironment}
/>
)}
{activeTab === "home" && isUserAdmin && (
)}
{activeTab === "users" && isUserAdmin && (
)}
{activeTab === "settings" && }
{activeTab === "profile" && (
setCurrentUser(updated)}
serverUsers={serverUsers}
onRefreshUsers={loadServerUsers}
onNavigateToUsers={() => handleNavClick("users")}
/>
)}
{activeTab === "help" && }
);
}