import { Check, Close, ContentCopy, ExpandMore, Launch, Public, PublicOff, Warning, } from '@mui/icons-material'; import { Box, Card, CardContent, Chip, Divider, IconButton, ToggleButton, ToggleButtonGroup, Tooltip, Typography, alpha, } from '@mui/material'; import { useState } from 'react'; import { Link } from 'react-router-dom'; import ServerData, { ServerSetting, ServerSettingsInfo, } from '../data/ServerData'; import CopyImageIcon from '../images/copy-image.png'; import { Accordion, AccordionDetails, AccordionSummary } from './Accordion'; export default function ServerCard({ server }: { server: ServerData }) { 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; } const renderSettingsChip = ([key, value]: [ string, boolean | string | number, ]) => { if (!ServerSettingsInfo[key]) return null; const transformValue = ( v: boolean | string | number, setting: ServerSetting ): string | number | boolean => { return setting.transform?.(v) ?? v; }; let chipValue: string | number | boolean | JSX.Element = transformValue( value, ServerSettingsInfo[key] ); if (typeof chipValue === 'boolean') { chipValue = chipValue ? ( ) : ( ); } return ( ) } icon={typeof chipValue === 'object' ? chipValue : undefined} size="small" className="m-1 pr-1" sx={{ '& .MuiChip-avatar': { width: 'auto', marginX: 0, order: 2, }, '& .MuiChip-icon': { marginX: 0, order: 2, }, '&> .MuiChip-label': { paddingRight: 0.5, }, boxShadow: '0px 3px 3px rgba(0, 0, 0, .25)', }} /> ); }; const expansions = [ RotZ , CoP , ToAU , WotG , SoA , ]; return ( }> {server.customizations['LOGIN.MAINT_MODE'] === 1 ? ( ) : ( {server.inactivity_counter > 0 ? ( ) : ( )} )} alpha(theme.palette.text.primary, 0.87)} sx={{ lineHeight: 1.0 }} > {server.name} {typeof server.customizations['API.WEBSITE'] === 'string' && server.customizations['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, }} /> )} {expansions} theme.palette.text.secondary} > {`Lv.${server.max_level}`} {server.customizations['MAIN.SERVER_MESSAGE'] && ( <> {server.customizations['MAIN.SERVER_MESSAGE']} > )} {Object.entries(server.customizations).map(renderSettingsChip)} {server.active_sessions} active sessions {server.login_limit !== 1 && ( event.preventDefault()} /> )} Updated: {new Date(server.updated).toLocaleString()} ); }