import { ArrowCircleUp, ContentCopy, ExpandMore, Info, Launch, Public, PublicOff, Warning, } from '@mui/icons-material'; import { Accordion, AccordionDetails, AccordionSummary, Box, Card, CardContent, Divider, IconButton, Tooltip, Typography, alpha, } from '@mui/material'; import { Children, ElementType, ReactNode, isValidElement, useState, } from 'react'; import { Link } from 'react-router-dom'; import { useThemeModeContext } from '../../context/ThemeContext'; import { ServerData } from '../../data/ServerData'; import CopyImageIcon from '../../images/copy-image.png'; import ExpansionBar from './ExpansionsBar'; import SettingsDataGrid from './SettingsDataGrid'; function scrollToTop() { window.scrollTo({ top: 0, behavior: 'smooth' }); } type ServerCardProps = { server: ServerData; children: ReactNode; }; export default function ServerCard({ server, children }: ServerCardProps) { const { themeMode } = useThemeModeContext(); const [clipboardTooltip, setClipboardTooltip] = useState('Copy server URL.'); const [clipboardTooltipOpen, setClipboardTooltipOpen] = useState(false); const handleClipboardTooltipClose = () => { setClipboardTooltipOpen(false); }; const handleClipboardTooltipOpen = () => { setClipboardTooltipOpen(true); }; const copyServerUrlToClipboard = async (text: string) => { try { navigator.clipboard.writeText(text); setClipboardTooltip('Copied server URL!'); handleClipboardTooltipOpen(); setTimeout(() => { handleClipboardTooltipClose(); setClipboardTooltip('Copy server URL.'); }, 3000); } catch (error) { handleClipboardTooltipOpen(); if (error instanceof Error) { setClipboardTooltip(error.message); } else { setClipboardTooltip('Something went wrong!'); } setTimeout(() => { handleClipboardTooltipClose(); setClipboardTooltip('Copy server URL.'); }, 3000); } }; function formatExternalUrl(url: string): string { // prepend 'https://' to the URL if it's not already there if (!/^https?:\/\//i.test(url)) { return `https://${url}`; } return url; } // Check if this is a detailed server card with a data grid const hasSpecificComponent = ( childrenProps: ReactNode, componentType: ElementType ): boolean => { const childrenArray = Children.toArray(childrenProps); return childrenArray.some( (child) => isValidElement(child) && child.type === componentType ); }; const isSettingsDataGridChild = hasSpecificComponent( children, SettingsDataGrid ); // Manually handle the accordion state to disable closing when detailed view const [expand, setExpand] = useState(isSettingsDataGridChild); const toggleAcordion = () => { if (!isSettingsDataGridChild) { setExpand((prev) => !prev); } }; return ( } onClick={toggleAcordion} sx={{ backgroundColor: (theme) => theme.palette.mode === 'dark' ? 'rgba(255, 255, 255, .05)' : 'rgba(0, 0, 0, .02)', '& .MuiAccordionSummary-content': { margin: 0, }, boxShadow: '0 0 10px rgba(0, 0, 0, 0.1)', minHeight: '32px', }} > {server.settings_summary['LOGIN.MAINT_MODE'] === 1 ? ( ) : (
{!server.up ? ( ) : ( )}
)}
{ event.stopPropagation(); }} sx={{ textDecoration: 'none', }} color={(theme) => alpha(theme.palette.text.primary, 0.5)} > {server.location}
alpha(theme.palette.text.primary, 0.87)} sx={{ lineHeight: 1.0 }} > {server.name} {typeof server.settings_summary['API.WEBSITE'] === 'string' && server.settings_summary['API.WEBSITE'] !== '' && ( { event.stopPropagation(); }} disableRipple > theme.typography.caption.fontSize, }} /> )} alpha(theme.palette.text.primary, 0.6)} > {server.url} {window.isSecureContext && ( { event.stopPropagation(); copyServerUrlToClipboard(server.url); }} disableRipple > theme.typography.caption.fontSize, }} /> )} theme.palette.text.secondary} > {`Lv.${server.max_level}`}
theme.palette.mode === 'dark' ? 'rgba(255, 255, 255, .03)' : 'rgba(0, 0, 0, .04)', }} > {server.settings_summary['MAIN.SERVER_MESSAGE'] && ( <> alpha(theme.palette.divider, 0.6)} > Server Message {server.settings_summary['MAIN.SERVER_MESSAGE']} )} alpha(theme.palette.divider, 0.6)} > Settings{!isSettingsDataGridChild && ' Summary'} {children}
{server.active_sessions} active sessions {server.login_limit !== 1 && ( event.preventDefault()} /> )} {/* */} Updated: {new Date(server.updated).toLocaleString()} {isSettingsDataGridChild ? ( ) : ( )}
); }