Skip to content

Commit

Permalink
Redesign management modals (#87)
Browse files Browse the repository at this point in the history
* redesign management modals

* small fixes

---------

Co-authored-by: Sergej <sakacszergej@gmail.com>
  • Loading branch information
TopETH and Szegoo committed Apr 26, 2024
1 parent 184e7eb commit 3adf70f
Show file tree
Hide file tree
Showing 17 changed files with 595 additions and 204 deletions.
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
.buttonContainer {
background:linear-gradient(180deg, #E84D68 0%, #AD2B49 100%);
background: linear-gradient(180deg, #e84d68 0%, #ad2b49 100%);
border-radius: 100px;
font-weight: 500;
text-transform: none;
padding: 0.5rem 1.25rem;
font-size: 0.8rem;
}
}
3 changes: 3 additions & 0 deletions src/components/Elements/Buttons/ProgressButton/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,21 @@ interface ProgressButtonProps {
label: string;
onClick: () => void;
loading: boolean;
disabled?: boolean;
}
export const ProgressButton = ({
label,
onClick,
loading,
disabled = false,
}: ProgressButtonProps) => {
return (
<LoadingButton
onClick={onClick}
variant='contained'
loading={loading}
className={styles.buttonContainer}
disabled={disabled}
>
{label}
</LoadingButton>
Expand Down
18 changes: 18 additions & 0 deletions src/components/Elements/SimpleRegionCard/index.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
.container {
display: flex;
flex-direction: column;
gap: 1.75rem;
padding: 1.25rem;
box-shadow: 2px 2px 55px rgba(0, 0, 0, 0.08);
}

.regionInfo {
display: flex;
justify-content: space-between;
align-items: center;
}

.timeInfo {
display: flex;
justify-content: space-between;
}
98 changes: 98 additions & 0 deletions src/components/Elements/SimpleRegionCard/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
import { Box, Paper, Stack, Typography, useTheme } from '@mui/material';
import { ApiPromise } from '@polkadot/api';
import { humanizer } from 'humanize-duration';
import TimeAgo from 'javascript-time-ago';
import en from 'javascript-time-ago/locale/en';
import { useCallback, useEffect, useState } from 'react';

import { timesliceToTimestamp } from '@/utils/functions';

import { useRelayApi } from '@/contexts/apis';
import { ApiState } from '@/contexts/apis/types';
import { useCommon } from '@/contexts/common';
import { RegionMetadata } from '@/models';

import styles from './index.module.scss';

interface SimpleRegionCardProps {
regionMetadata: RegionMetadata;
}

export const SimpleRegionCard = ({ regionMetadata }: SimpleRegionCardProps) => {
TimeAgo.addLocale(en);
// Create formatter (English).
const timeAgo = new TimeAgo('en-US');

const formatDuration = humanizer({ units: ['w', 'd', 'h'], round: true });

const {
state: { api: relayApi, apiState: relayApiState },
} = useRelayApi();

const theme = useTheme();

const [beginTimestamp, setBeginTimestamp] = useState(0);
const [endTimestamp, setEndTimestamp] = useState(0);

const { region } = regionMetadata;
const { timeslicePeriod } = useCommon();

const setTimestamps = useCallback(
(api: ApiPromise) => {
timesliceToTimestamp(api, region.getBegin(), timeslicePeriod).then(
(value) => setBeginTimestamp(value)
);
timesliceToTimestamp(api, region.getEnd(), timeslicePeriod).then(
(value) => setEndTimestamp(value)
);
},
[region, timeslicePeriod]
);

useEffect(() => {
if (!relayApi || relayApiState !== ApiState.READY) {
return;
}

setTimestamps(relayApi);
}, [relayApi, relayApiState, setTimestamps]);
return (
<Paper className={styles.container}>
<Box className={styles.regionInfo}>
<Box>
<Typography
variant='subtitle1'
sx={{ color: theme.palette.common.black }}
>
{regionMetadata.name}
</Typography>
<Typography
variant='subtitle2'
sx={{ color: theme.palette.text.primary }}
>
{`Duration: ${formatDuration(endTimestamp - beginTimestamp)}`}
</Typography>
</Box>
<Box>
<Typography
sx={{ color: theme.palette.common.black }}
>{`Core Index: #${region.getCore()}`}</Typography>
</Box>
</Box>
<Box className={styles.timeInfo}>
<Stack direction='column'>
<Typography>Begin:</Typography>
<Typography sx={{ color: theme.palette.common.black }}>
{timeAgo.format(beginTimestamp)}
</Typography>
</Stack>
<Stack direction='column'>
<Typography>End:</Typography>
<Typography sx={{ color: theme.palette.common.black }}>
{timeAgo.format(endTimestamp)}
</Typography>
</Stack>
</Box>
</Paper>
);
};
1 change: 1 addition & 0 deletions src/components/Elements/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,5 @@ export * from './Progress';
export * from './RegionCard';
export * from './SaleInfoPanel';
export * from './Selectors';
export * from './SimpleRegionCard';
export * from './StatusIndicator';
7 changes: 7 additions & 0 deletions src/components/Modals/AddTask/index.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
.container {
display: flex;
flex-direction: column;
gap: 1.55rem;
padding: 1.25rem;
width: 30rem;
}
109 changes: 109 additions & 0 deletions src/components/Modals/AddTask/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
import {
Button,
Dialog,
DialogActions,
DialogContent,
DialogProps,
Input,
Stack,
TextField,
Typography,
useTheme,
} from '@mui/material';
import { useState } from 'react';

import { ActionButton } from '@/components/Elements';

import { useRelayApi } from '@/contexts/apis';
import { useTasks } from '@/contexts/tasks';
import { useToast } from '@/contexts/toast';
import { TaskMetadata } from '@/models';

import styles from './index.module.scss';

type AddTaskModalProps = DialogProps & {
onClose: () => void;
};

export const AddTaskModal = ({ onClose, ...props }: AddTaskModalProps) => {
const theme = useTheme();

const { paraIds } = useRelayApi();
const { toastError } = useToast();
const { tasks, addTask } = useTasks();

const [taskId, setTaskId] = useState<number>();
const [taskName, setTaskName] = useState<string>('');

const onAdd = () => {
if (taskId === undefined) {
toastError('Please input the Para ID');
return;
}
if (!taskName) {
toastError('Invalid task name.');
return;
}
const existing = tasks.find((task) => task.id === taskId);
if (existing) {
toastError('Failed to add task. Duplicated ID');
} else if (!paraIds.includes(taskId)) {
toastError(`Para ID ${taskId} doesn't exist.`);
} else {
addTask({ id: taskId, usage: 0, name: taskName } as TaskMetadata);
setTaskId(undefined);
setTaskName('');
}
};

return (
<Dialog {...props}>
<DialogContent className={styles.container}>
<Typography
variant='subtitle1'
sx={{ color: theme.palette.common.black }}
>
Add New Task
</Typography>
<Stack direction='column' gap={1}>
<Stack direction='column' gap={2}>
<Typography
variant='subtitle2'
sx={{ color: theme.palette.common.black }}
>
TaskID / ParaID:
</Typography>
<Input
type='number'
value={taskId || ''}
onChange={(e) => setTaskId(Number(e.target.value))}
size='small'
fullWidth
placeholder='Input TaskID / ParaID'
/>
</Stack>
<Stack direction='column' gap={2}>
<Typography
variant='subtitle2'
sx={{ color: theme.palette.common.black }}
>
Name:
</Typography>
<TextField
value={taskName}
onChange={(e) => setTaskName(e.target.value)}
size='small'
fullWidth
/>
</Stack>
</Stack>
</DialogContent>
<DialogActions>
<Button onClick={onClose} variant='outlined'>
Cancel
</Button>
<ActionButton label='Add Task' onClick={onAdd} />
</DialogActions>
</Dialog>
);
};
22 changes: 22 additions & 0 deletions src/components/Modals/Interlace/index.module.scss
Original file line number Diff line number Diff line change
@@ -1,3 +1,19 @@
.container {
display: flex;
flex-direction: column;
gap: 0.75rem;
width: 40rem;
padding-bottom: 0;
}

.content {
display: flex;
flex-direction: column;
gap: 0.75rem;
margin: 0 0 1rem 0;
padding: 1.25rem;
}

.slider {
margin-top: 2rem;
margin-left: auto;
Expand All @@ -9,4 +25,10 @@
margin-top: 2rem;
margin-left: auto;
margin-right: auto;
}

.mask {
width: 100%;
overflow-x: clip;
font-size: 12px;
}
Loading

0 comments on commit 3adf70f

Please sign in to comment.