Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update overview page top section #175

Merged
merged 9 commits into from
Feb 25, 2023
3 changes: 2 additions & 1 deletion src/components/Atoms/Label.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import clsx from 'clsx';

export type LabelSize = 'small' | 'medium' | 'large';

export type LabelColor = 'green' | 'yellow' | 'red' | 'gray';
export type LabelColor = 'green' | 'yellow' | 'red' | 'gray' | 'blue';

export default function Label({
size = 'small',
Expand All @@ -28,6 +28,7 @@ export default function Label({
}[size],
{
green: 'bg-green-faded/25 text-green',
blue: 'bg-blue-faded/25 text-blue-150',
yellow: 'bg-yellow-faded/25 text-yellow',
red: 'bg-red-faded/25 text-red',
gray: 'bg-gray-faded/30 text-gray-300',
Expand Down
16 changes: 13 additions & 3 deletions src/components/ClipboardTextfield.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,19 @@ import { faClone } from '@fortawesome/free-solid-svg-icons';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import Tooltip from 'rc-tooltip';
import { toast } from 'react-toastify';
import clsx from 'clsx';
import { LabelColor } from './Atoms/Label';

export default function ClipboardTextfield({
color = 'gray',
text,
textToCopy,
className,
}: {
text: string;
textToCopy?: string;
className?: string;
color?: LabelColor;
}) {
const onClickCopy = (e: React.MouseEvent<HTMLSpanElement>) => {
e.stopPropagation();
Expand All @@ -32,12 +36,18 @@ export default function ClipboardTextfield({
onClick={onClickCopy}
>
<div className={`select-none`}>
{/* TODO develop custom tooltip component */}
{text}&nbsp;&nbsp;
ViridianCitrus marked this conversation as resolved.
Show resolved Hide resolved
<FontAwesomeIcon
className={`mr-2 text-gray-faded/30 group-hover:text-gray-500`}
className={clsx({
gray: `mr-2 text-gray-faded/25 group-hover:text-gray-500`,
blue: `mr-2 text-blue-faded/25 group-hover:text-blue-150`,
green: 'mr-2 text-green-faded/25 group-hover:text-green',
yellow: 'mr-2 text-yellow-faded/25 group-hover:text-yellow',
red: 'mr-2 text-red-faded/25 group-hover:text-red',
}[color])}
icon={faClone}
/>
{/* TODO develop custom tooltip component */}
{text}&nbsp;&nbsp;
</div>
</div>
</Tooltip>
Expand Down
101 changes: 101 additions & 0 deletions src/components/Minecraft/MinecraftOverview.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
import { Tab } from '@headlessui/react';
import ClipboardTextfield from 'components/ClipboardTextfield';
import GameConsole from 'components/GameConsole';
import DashboardCard from 'components/DashboardCard';
import Label from 'components/Atoms/Label';
import { updateInstance } from 'data/InstanceList';
import { LodestoneContext } from 'data/LodestoneContext';
import { useContext, useEffect, useState } from 'react';
import { axiosPutSingleValue, stateToLabelColor } from 'utils/util';
import EditableTextfield from 'components/EditableTextfield';
import { useQueryClient } from '@tanstack/react-query';
import MinecraftPerformanceCard from 'components/Minecraft/MinecraftPerformanceCard';
import FileViewer from 'components/FileViewer/FileViewer';
import { InstanceContext } from 'data/InstanceContext';
import GameIcon from 'components/Atoms/GameIcon';
import { useGlobalSettings } from 'data/GlobalSettings';

import { useDocumentTitle } from 'usehooks-ts';

const MinecraftOverview = () => {
useDocumentTitle('Dashboard - Lodestone');
const { core } = useContext(LodestoneContext);
const { address } = core;
const { selectedInstance: instance } = useContext(InstanceContext);
const { data: globalSettings } = useGlobalSettings();
const domain = (globalSettings?.domain ?? address) || 'localhost';
const queryClient = useQueryClient();
const uuid = instance?.uuid;
const [selectedTabIndex, setSelectedTabIndex] = useState(0);

if (!instance || !uuid) {
return (
<div
className="relative flex h-full w-full flex-row justify-center overflow-y-auto px-4 pt-8 pb-10 @container"
key={uuid}
>
<div className="flex h-fit min-h-full w-full grow flex-col items-start gap-2">
<div className="flex min-w-0 flex-row items-center gap-4">
<h1 className="dashboard-instance-heading truncate whitespace-pre">
Instance not found
</h1>
</div>
</div>
</div>
);
}

const labelColor = stateToLabelColor[instance.state];

// tablist is map from GameType to tabs


const setInstanceName = async (name: string) => {
await axiosPutSingleValue<void>(`/instance/${uuid}/name`, name);
updateInstance(uuid, queryClient, (oldData) => ({
...oldData,
name,
}));
};

return (
<>
<div
className="relative flex h-full w-full max-w-2xl flex-col justify-center @container"
key={uuid}
>
{/* main content container */}
<div className="flex w-full grow flex-col items-stretch gap-2 ">
<div className="flex w-full min-w-0 flex-row items-center gap-4">
ViridianCitrus marked this conversation as resolved.
Show resolved Hide resolved
<EditableTextfield
initialText={instance.name}
type={'heading'}
onSubmit={setInstanceName}
placeholder="No name"
containerClassName="min-w-0"
/>
</div>
<div className="-mt-2 mb-2 flex flex-row flex-wrap items-center gap-4">
<GameIcon
game_type={instance.game_type}
game_flavour={instance.flavour}
className="h-6 w-6"
/>
<Label size="large" color={labelColor}>
{instance.state}
</Label>
<Label size="large" color={'blue'}>
Player Count {instance.player_count}/{instance.max_player_count}
</Label>
<Label size="large" color={'blue'}>
<ClipboardTextfield text={`${domain}:${instance.port}`} color='blue' />
</Label>
</div>
</div>
</div>
<MinecraftPerformanceCard/>
</>
);
};

export default MinecraftOverview;
15 changes: 8 additions & 7 deletions src/data/InstanceTabListMap.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@ import GameConsole from 'components/GameConsole';
import MinecraftGeneralCard from 'components/Minecraft/MinecraftGeneralCard';
import MinecraftSettingCard from 'components/Minecraft/MinecraftSettingCard';
import FileViewer from 'components/FileViewer';
import MinecraftPerformanceCard from 'components/Minecraft/MinecraftPerformanceCard';
import DashboardCard from 'components/DashboardCard';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import MinecraftOverview from 'components/Minecraft/MinecraftOverview';
import MinecraftPerformanceCard from 'components/Minecraft/MinecraftPerformanceCard';

import {
faChartLine,
Expand All @@ -22,15 +23,11 @@ const InstanceTabListMap = {
path: 'overview',
width: 'max-w-4xl',
icon: <FontAwesomeIcon icon={faChartLine} />,
content: (
<>
<p>Work in Progress</p>
<MinecraftPerformanceCard />
</>
),
content: <MinecraftOverview/>,
},
{
title: 'Settings',
displayTitle: 'Settings',
path: 'settings',
width: 'max-w-2xl',
icon: <FontAwesomeIcon icon={faCog} />,
Expand All @@ -43,20 +40,23 @@ const InstanceTabListMap = {
},
{
title: 'Console',
displayTitle: 'Console',
path: 'console',
width: 'max-w-6xl',
icon: <FontAwesomeIcon icon={faServer} />,
content: <GameConsole />,
},
{
title: 'Files',
displayTitle: 'Files',
path: 'files',
width: 'max-w-6xl',
icon: <FontAwesomeIcon icon={faFolder} />,
content: <FileViewer />,
},
{
title: 'Tasks',
displayTitle: 'Tasks',
path: 'tasks',
width: 'max-w-4xl',
icon: <FontAwesomeIcon icon={faCodeCompare} />,
Expand All @@ -75,6 +75,7 @@ const InstanceTabListMap = {
},
{
title: 'Event Logs',
displayTitle: 'Event Logs',
path: 'logs',
width: 'max-w-4xl',
icon: <FontAwesomeIcon icon={faInbox} />,
Expand Down
45 changes: 25 additions & 20 deletions src/pages/InstanceTabs/InstanceTabs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -87,26 +87,31 @@ const InstanceTabs = () => {
className={cn("relative mx-auto flex h-full w-full flex-row justify-center @container", tab.width)}
key={uuid}
>
<div
className="gutter-stable -mx-3 flex grow flex-row items-stretch overflow-y-auto pl-4 pr-2"
key={`${instance.name}-${tab.title}`}
>
<div className="flex h-fit min-h-full w-full flex-col gap-8 pt-10 pb-8 focus:outline-none">
<div className="flex font-title text-h1 font-bold leading-tight text-gray-300">
{tab.title}
{tab.title === 'Console' && (
<Label
size="medium"
className="ml-2 mt-[6px]"
color={stateToLabelColor[instance.state]}
>
{instance.state}
</Label>
)}
</div>
{tab.content}
</div>
</div>
{InstanceTabListMap[instance.game_type].map(
(tab) =>
tab.path === path && (
<div
className="gutter-stable -mx-3 flex grow flex-row items-stretch overflow-y-auto pl-4 pr-2"
key={`${instance.name}-${tab.title}`}
>
<div className="flex h-fit min-h-full w-full flex-col gap-16 pt-6 pb-10 focus:outline-none">
{tab.displayTitle && <div className="flex font-title text-h1 font-bold leading-tight text-gray-300">
{tab.displayTitle}
{tab.title === 'Console' && (
<Label
size="medium"
className="ml-2 mt-[6px]"
color={stateToLabelColor[instance.state]}
>
{instance.state}
</Label>
)}
</div>}
{tab.content}
</div>
</div>
)
)}
</div>
);
};
Expand Down
1 change: 1 addition & 0 deletions tailwind.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ module.exports = {
transparent: 'transparent', //! what
current: 'currentColor',
blue: {
150: '#69C9FF',
200: '#59B2F3',
300: '#1D8EB2',
DEFAULT: '#1D8EB2',
Expand Down