ui(admin): add "working" React admin ui
This commit is contained in:
parent
d1c7494933
commit
5402584508
199 changed files with 13387 additions and 151 deletions
|
@ -48,9 +48,9 @@ export default () => {
|
|||
{!data && isValidating ? (
|
||||
<Spinner centered />
|
||||
) : !data?.items.length ? (
|
||||
<p className={'text-sm text-center text-gray-400'}>No activity logs available for this server.</p>
|
||||
<p className={'text-sm text-center text-slate-400'}>No activity logs available for this server.</p>
|
||||
) : (
|
||||
<div className={'bg-gray-700'}>
|
||||
<div className={'bg-slate-700'}>
|
||||
{data?.items.map(activity => (
|
||||
<ActivityLogEntry key={activity.id} activity={activity}>
|
||||
<span />
|
||||
|
|
|
@ -140,7 +140,7 @@ export default ({ backup }: Props) => {
|
|||
Your server will be stopped. You will not be able to control the power state, access the file
|
||||
manager, or create additional backups until completed.
|
||||
</p>
|
||||
<p css={tw`mt-4 -mb-2 bg-gray-700 p-3 rounded`}>
|
||||
<p css={tw`mt-4 -mb-2 bg-slate-700 p-3 rounded`}>
|
||||
<label htmlFor={'restore_truncate'} css={tw`text-base flex items-center cursor-pointer`}>
|
||||
<Input
|
||||
type={'checkbox'}
|
||||
|
@ -169,7 +169,7 @@ export default ({ backup }: Props) => {
|
|||
renderToggle={onClick => (
|
||||
<button
|
||||
onClick={onClick}
|
||||
css={tw`text-gray-200 transition-colors duration-150 hover:text-gray-100 p-2`}
|
||||
css={tw`text-slate-200 transition-colors duration-150 hover:text-slate-100 p-2`}
|
||||
>
|
||||
<FontAwesomeIcon icon={faEllipsisH} />
|
||||
</button>
|
||||
|
@ -211,7 +211,7 @@ export default ({ backup }: Props) => {
|
|||
) : (
|
||||
<button
|
||||
onClick={() => setModal('delete')}
|
||||
css={tw`text-gray-200 transition-colors duration-150 hover:text-gray-100 p-2`}
|
||||
css={tw`text-slate-200 transition-colors duration-150 hover:text-slate-100 p-2`}
|
||||
>
|
||||
<FontAwesomeIcon icon={faTrashAlt} />
|
||||
</button>
|
||||
|
|
|
@ -11,7 +11,7 @@ interface ChartBlockProps {
|
|||
export default ({ title, legend, children }: ChartBlockProps) => (
|
||||
<div className={classNames(styles.chart_container, 'group')}>
|
||||
<div className={'flex items-center justify-between px-4 py-2'}>
|
||||
<h3 className={'font-header transition-colors duration-100 group-hover:text-gray-50'}>{title}</h3>
|
||||
<h3 className={'font-header transition-colors duration-100 group-hover:text-slate-50'}>{title}</h3>
|
||||
{legend && <p className={'text-sm flex items-center'}>{legend}</p>}
|
||||
</div>
|
||||
<div className={'z-10 ml-2'}>{children}</div>
|
||||
|
|
|
@ -232,7 +232,7 @@ export default () => {
|
|||
/>
|
||||
<div
|
||||
className={classNames(
|
||||
'text-gray-100 peer-focus:text-gray-50 peer-focus:animate-pulse',
|
||||
'text-slate-100 peer-focus:text-slate-50 peer-focus:animate-pulse',
|
||||
styles.command_icon,
|
||||
)}
|
||||
>
|
||||
|
|
|
@ -35,7 +35,7 @@ function ServerConsoleContainer() {
|
|||
)}
|
||||
<div className={'grid grid-cols-4 gap-4 mb-4'}>
|
||||
<div className={'hidden sm:block sm:col-span-2 lg:col-span-3 pr-4'}>
|
||||
<h1 className={'font-header text-2xl text-gray-50 leading-relaxed line-clamp-1'}>{name}</h1>
|
||||
<h1 className={'font-header text-2xl text-slate-50 leading-relaxed line-clamp-1'}>{name}</h1>
|
||||
<p className={'text-sm line-clamp-2'}>{description}</p>
|
||||
</div>
|
||||
<div className={'col-span-4 sm:col-span-2 lg:col-span-1 self-end'}>
|
||||
|
|
|
@ -38,7 +38,7 @@ function Limit({ limit, children }: { limit: string | null; children: ReactNode
|
|||
return (
|
||||
<>
|
||||
{children}
|
||||
<span className={'ml-1 text-gray-300 text-[70%] select-none'}>/ {limit || <>∞</>}</span>
|
||||
<span className={'ml-1 text-slate-300 text-[70%] select-none'}>/ {limit || <>∞</>}</span>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
@ -112,7 +112,7 @@ function ServerDetailsBlock({ className }: { className?: string }) {
|
|||
</StatBlock>
|
||||
<StatBlock icon={faMicrochip} title={'CPU Load'} color={getBackgroundColor(stats.cpu, limits.cpu)}>
|
||||
{status === 'offline' ? (
|
||||
<span className={'text-gray-400'}>Offline</span>
|
||||
<span className={'text-slate-400'}>Offline</span>
|
||||
) : (
|
||||
<Limit limit={textLimits.cpu}>{stats.cpu.toFixed(2)}%</Limit>
|
||||
)}
|
||||
|
@ -123,7 +123,7 @@ function ServerDetailsBlock({ className }: { className?: string }) {
|
|||
color={getBackgroundColor(stats.memory / 1024, limits.memory * 1024)}
|
||||
>
|
||||
{status === 'offline' ? (
|
||||
<span className={'text-gray-400'}>Offline</span>
|
||||
<span className={'text-slate-400'}>Offline</span>
|
||||
) : (
|
||||
<Limit limit={textLimits.memory}>{bytesToString(stats.memory)}</Limit>
|
||||
)}
|
||||
|
@ -132,10 +132,10 @@ function ServerDetailsBlock({ className }: { className?: string }) {
|
|||
<Limit limit={textLimits.disk}>{bytesToString(stats.disk)}</Limit>
|
||||
</StatBlock>
|
||||
<StatBlock icon={faCloudDownloadAlt} title={'Network (Inbound)'}>
|
||||
{status === 'offline' ? <span className={'text-gray-400'}>Offline</span> : bytesToString(stats.rx)}
|
||||
{status === 'offline' ? <span className={'text-slate-400'}>Offline</span> : bytesToString(stats.rx)}
|
||||
</StatBlock>
|
||||
<StatBlock icon={faCloudUploadAlt} title={'Network (Outbound)'}>
|
||||
{status === 'offline' ? <span className={'text-gray-400'}>Offline</span> : bytesToString(stats.tx)}
|
||||
{status === 'offline' ? <span className={'text-slate-400'}>Offline</span> : bytesToString(stats.tx)}
|
||||
</StatBlock>
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -22,22 +22,22 @@ function StatBlock({ title, copyOnClick, icon, color, className, children }: Sta
|
|||
|
||||
return (
|
||||
<CopyOnClick text={copyOnClick}>
|
||||
<div className={classNames(styles.stat_block, 'bg-gray-600', className)}>
|
||||
<div className={classNames(styles.status_bar, color || 'bg-gray-700')} />
|
||||
<div className={classNames(styles.icon, color || 'bg-gray-700')}>
|
||||
<div className={classNames(styles.stat_block, 'bg-slate-600', className)}>
|
||||
<div className={classNames(styles.status_bar, color || 'bg-slate-700')} />
|
||||
<div className={classNames(styles.icon, color || 'bg-slate-700')}>
|
||||
<Icon
|
||||
icon={icon}
|
||||
className={classNames({
|
||||
'text-gray-100': !color || color === 'bg-gray-700',
|
||||
'text-gray-50': color && color !== 'bg-gray-700',
|
||||
'text-slate-100': !color || color === 'bg-slate-700',
|
||||
'text-slate-50': color && color !== 'bg-slate-700',
|
||||
})}
|
||||
/>
|
||||
</div>
|
||||
<div className={'flex flex-col justify-center overflow-hidden w-full'}>
|
||||
<p className={'font-header leading-tight text-xs md:text-sm text-gray-200'}>{title}</p>
|
||||
<p className={'font-header leading-tight text-xs md:text-sm text-slate-200'}>{title}</p>
|
||||
<div
|
||||
ref={ref}
|
||||
className={'h-[1.75rem] w-full font-semibold text-gray-50 truncate'}
|
||||
className={'h-[1.75rem] w-full font-semibold text-slate-50 truncate'}
|
||||
style={{ fontSize }}
|
||||
>
|
||||
{children}
|
||||
|
|
|
@ -45,13 +45,13 @@ const options: ChartOptions<'line'> = {
|
|||
type: 'linear',
|
||||
grid: {
|
||||
display: true,
|
||||
color: theme('colors.gray.700'),
|
||||
color: theme('colors.slate.700'),
|
||||
drawBorder: false,
|
||||
},
|
||||
ticks: {
|
||||
display: true,
|
||||
count: 3,
|
||||
color: theme('colors.gray.200'),
|
||||
color: theme('colors.slate.200'),
|
||||
font: {
|
||||
family: theme('fontFamily.sans'),
|
||||
size: 11,
|
||||
|
|
|
@ -41,7 +41,7 @@
|
|||
}
|
||||
|
||||
&::-webkit-scrollbar-thumb {
|
||||
@apply bg-gray-900;
|
||||
@apply bg-slate-900;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -51,7 +51,7 @@
|
|||
}
|
||||
|
||||
& .command_input {
|
||||
@apply relative bg-gray-900 px-2 text-gray-100 pl-10 pr-4 py-2 w-full font-mono text-sm sm:rounded-b;
|
||||
@apply relative bg-slate-900 px-2 text-slate-100 pl-10 pr-4 py-2 w-full font-mono text-sm sm:rounded-b;
|
||||
@apply focus:ring-0 outline-none focus-visible:outline-none;
|
||||
@apply border-0 border-b-2 border-transparent transition-colors duration-100;
|
||||
@apply active:border-cyan-500 focus:border-cyan-500;
|
||||
|
@ -59,5 +59,5 @@
|
|||
}
|
||||
|
||||
.chart_container {
|
||||
@apply bg-gray-600 rounded shadow-lg pt-2 border-b-4 border-gray-700 relative;
|
||||
@apply bg-slate-600 rounded shadow-lg pt-2 border-b-4 border-slate-700 relative;
|
||||
}
|
||||
|
|
|
@ -138,7 +138,7 @@ const FileDropdownMenu = ({ file }: { file: FileObject }) => {
|
|||
onConfirmed={doDeletion}
|
||||
>
|
||||
You will not be able to recover the contents of
|
||||
<span className={'font-semibold text-gray-50'}>{file.name}</span> once deleted.
|
||||
<span className={'font-semibold text-slate-50'}>{file.name}</span> once deleted.
|
||||
</Dialog.Confirm>
|
||||
<DropdownMenu
|
||||
ref={onClickRef}
|
||||
|
|
|
@ -42,7 +42,7 @@ const FileUploadList = () => {
|
|||
return (
|
||||
<div className={'space-y-2 mt-6'}>
|
||||
{uploads.map(([name, file]) => (
|
||||
<div key={name} className={'flex items-center space-x-3 bg-gray-700 p-3 rounded'}>
|
||||
<div key={name} className={'flex items-center space-x-3 bg-slate-700 p-3 rounded'}>
|
||||
<Tooltip content={`${Math.floor((file.loaded / file.total) * 100)}%`} placement={'left'}>
|
||||
<div className={'flex-shrink-0'}>
|
||||
<Spinner progress={(file.loaded / file.total) * 100} className={'w-6 h-6'} />
|
||||
|
@ -51,7 +51,7 @@ const FileUploadList = () => {
|
|||
<Code className={'flex-1 truncate'}>{name}</Code>
|
||||
<button
|
||||
onClick={cancelFileUpload.bind(this, name)}
|
||||
className={'text-gray-500 hover:text-gray-200 transition-colors duration-75'}
|
||||
className={'text-slate-500 hover:text-slate-200 transition-colors duration-75'}
|
||||
>
|
||||
<XIcon className={'w-5 h-5'} />
|
||||
</button>
|
||||
|
|
|
@ -75,7 +75,7 @@ const MassActionsBar = () => {
|
|||
>
|
||||
<p className="mb-2">
|
||||
Are you sure you want to delete
|
||||
<span className="font-semibold text-gray-50">{selectedFiles.length} files</span>? This is a
|
||||
<span className="font-semibold text-slate-50">{selectedFiles.length} files</span>? This is a
|
||||
permanent action and the files cannot be recovered.
|
||||
</p>
|
||||
{selectedFiles.slice(0, 15).map(file => (
|
||||
|
|
|
@ -96,7 +96,7 @@ const AllocationRow = ({ allocation }: Props) => {
|
|||
</div>
|
||||
<div className={'flex justify-end space-x-4 mt-4 w-full md:mt-0 md:w-48'}>
|
||||
{allocation.isDefault ? (
|
||||
<Button size={Button.Sizes.Small} className={'!text-gray-50 !bg-blue-600'} disabled>
|
||||
<Button size={Button.Sizes.Small} className={'!text-slate-50 !bg-blue-600'} disabled>
|
||||
Primary
|
||||
</Button>
|
||||
) : (
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue