This commit is contained in:
Nicola Benaglia 2025-06-11 23:29:57 +02:00
parent a65ea59ba4
commit 9fb4b0f8aa
3 changed files with 409 additions and 350 deletions

View File

@ -1763,7 +1763,7 @@ export const Group = ({
sx={{ sx={{
background: background:
direct?.address === selectedDirect?.address && direct?.address === selectedDirect?.address &&
theme.palette.background.default, theme.palette.background.paper,
borderRadius: '2px', borderRadius: '2px',
cursor: 'pointer', cursor: 'pointer',
display: 'flex', display: 'flex',
@ -1782,7 +1782,7 @@ export const Group = ({
<ListItemAvatar> <ListItemAvatar>
<Avatar <Avatar
sx={{ sx={{
background: theme.palette.background.default, background: theme.palette.background.paper,
color: theme.palette.text.primary, color: theme.palette.text.primary,
}} }}
alt={direct?.name || direct?.address} alt={direct?.name || direct?.address}
@ -1829,6 +1829,7 @@ export const Group = ({
fontSize: '16px', fontSize: '16px',
}} }}
/> />
{direct?.sender !== myAddress && {direct?.sender !== myAddress &&
direct?.timestamp && direct?.timestamp &&
((!timestampEnterData[direct?.address] && ((!timestampEnterData[direct?.address] &&
@ -1939,7 +1940,7 @@ export const Group = ({
setInfo={setInfoSnack} setInfo={setInfoSnack}
/> />
<div // TODO use Box <Box
style={{ style={{
alignItems: 'flex-start', alignItems: 'flex-start',
display: 'flex', display: 'flex',
@ -2007,7 +2008,7 @@ export const Group = ({
<> <>
<Box <Box
sx={{ sx={{
background: theme.palette.background.default, background: theme.palette.background.paper,
bottom: !(desktopViewMode === 'chat') ? 'unset' : '0px', bottom: !(desktopViewMode === 'chat') ? 'unset' : '0px',
left: !(desktopViewMode === 'chat') ? '-100000px' : '0px', left: !(desktopViewMode === 'chat') ? '-100000px' : '0px',
opacity: !(desktopViewMode === 'chat') ? 0 : 1, opacity: !(desktopViewMode === 'chat') ? 0 : 1,
@ -2461,7 +2462,7 @@ export const Group = ({
}} }}
/> />
<WalletsAppWrapper /> <WalletsAppWrapper />
</div> </Box>
</> </>
); );
}; };

View File

@ -13,12 +13,20 @@ import {
IconButton, IconButton,
Paper, Paper,
Snackbar, Snackbar,
Tab,
Tabs,
Toolbar, Toolbar,
Typography, Typography,
useTheme, useTheme,
} from '@mui/material'; } from '@mui/material';
import Grid from '@mui/material/Grid'; import Grid from '@mui/material/Grid';
import { useCallback, useEffect, useMemo, useState } from 'react'; import {
SyntheticEvent,
useCallback,
useEffect,
useMemo,
useState,
} from 'react';
import CloseIcon from '@mui/icons-material/Close'; import CloseIcon from '@mui/icons-material/Close';
import { getBaseApiReact } from '../../App'; import { getBaseApiReact } from '../../App';
import { import {
@ -46,6 +54,7 @@ export const Minting = ({ setIsOpenMinting, myAddress, show }) => {
const [openSnack, setOpenSnack] = useState(false); const [openSnack, setOpenSnack] = useState(false);
const [isLoading, setIsLoading] = useState(false); const [isLoading, setIsLoading] = useState(false);
const [adminInfo, setAdminInfo] = useState({}); const [adminInfo, setAdminInfo] = useState({});
const [valueMintingTab, setValueMintingTab] = useState(0);
const { isShow: isShowNext, onOk, show: showNext } = useModal(); const { isShow: isShowNext, onOk, show: showNext } = useModal();
const theme = useTheme(); const theme = useTheme();
const { t } = useTranslation([ const { t } = useTranslation([
@ -110,6 +119,13 @@ export const Minting = ({ setIsOpenMinting, myAddress, show }) => {
} }
}; };
function a11yProps(index: number) {
return {
id: `simple-tab-${index}`,
'aria-controls': `simple-tabpanel-${index}`,
};
}
const getAccountInfo = async (address: string, others?: boolean) => { const getAccountInfo = async (address: string, others?: boolean) => {
try { try {
if (!others) { if (!others) {
@ -514,6 +530,10 @@ export const Minting = ({ setIsOpenMinting, myAddress, show }) => {
</Grid> </Grid>
); );
const handleChange = (event: SyntheticEvent, newValue: number) => {
setValueMintingTab(newValue);
};
return ( return (
<Dialog <Dialog
open={true} open={true}
@ -551,380 +571,418 @@ export const Minting = ({ setIsOpenMinting, myAddress, show }) => {
</Toolbar> </Toolbar>
</AppBar> </AppBar>
<DialogContent <Box sx={{ borderBottom: 1, borderColor: 'divider' }}>
sx={{ <Tabs value={setValueMintingTab} onChange={handleChange}>
position: 'relative', <Tab label="Minting Details" {...a11yProps(0)} />
}} <Tab label="Item Two" {...a11yProps(1)} />
> <Tab label="Item Three" {...a11yProps(2)} />
{isLoading && ( </Tabs>
<Box </Box>
{valueMintingTab === 0 && (
<>
<DialogContent
sx={{ sx={{
alignItems: 'center', position: 'relative',
bottom: 0,
display: 'flex',
justifyContent: 'center',
left: 0,
position: 'absolute',
right: 0,
top: 0,
}} }}
> >
<FidgetSpinner <Container maxWidth="md" sx={{ py: 4 }}>
ariaLabel="fidget-spinner-loading" <Paper elevation={3} sx={{ p: 3, mb: 4, borderRadius: '10px' }}>
height="80" <Typography variant="h6" gutterBottom>
visible={true} Blockchain Statistics
width="80" </Typography>
wrapperClass="fidget-spinner-wrapper"
wrapperStyle={{}}
/>
</Box>
)}
<Card <Grid container spacing={2}>
sx={{ <StatCard
backgroundColor: theme.palette.background.default, label="Avg. Qortal Blocktime"
padding: '10px', value="72.84 Seconds"
}} />
> <StatCard
<Typography> label="Avg. Blocks Per Day"
{t('auth:account.account_one', { value="1186.16 Blocks"
postProcess: 'capitalizeFirstChar', />
})} <StatCard
: {handleNames(accountInfo?.address)} label="Avg. Created QORT Per Day"
</Typography> value="3558.48 QORT"
/>
</Grid>
</Paper>
<Typography> <Paper elevation={3} sx={{ p: 3, mb: 4, borderRadius: '10px' }}>
{t('core:level', { <Typography variant="h6" gutterBottom>
postProcess: 'capitalizeFirstChar', Minting Account Details
})} </Typography>
: {accountInfo?.level}
</Typography>
<Typography> <Grid container spacing={2}>
{t('group:message.generic.next_level', { <StatCard label="Current Status" value="(Minting)" />
postProcess: 'capitalizeFirstChar', <StatCard label="Current Level" value="Level 4" />
})}{' '} <StatCard
{_levelUpBlocks()} label="Blocks To Next Level"
</Typography> value="139467 Blocks"
/>
</Grid>
<Typography> <Box mt={2} textAlign="center">
{t('group:message.generic.node_minting', { <Typography>
postProcess: 'capitalizeFirstChar', With a 24/7 Minting you will reach level 5 in{' '}
})}{' '} <strong>117.58 days</strong>!
{nodeInfos?.isMintingPossible?.toString()} </Typography>
</Typography> </Box>
</Card> </Paper>
<Spacer height="10px" /> <Paper elevation={3} sx={{ p: 3, borderRadius: '10px' }}>
<Typography variant="h6" gutterBottom>
Minting Rewards Info
</Typography>
{isPartOfMintingGroup && !accountIsMinting && ( <Grid container spacing={2}>
<Box <StatCard label="Current Tier" value="Tier 2 (Level 3 + 4)" />
<StatCard
label="Total Minters in The Tier"
value="77 Minters"
/>
<StatCard label="Tier Share Per Block" value="13%" />
<StatCard
label="Est. Reward Per Block"
value="0.00506494 QORT"
/>
<StatCard
label="Est. Reward Per Day"
value="6.00782338 QORT"
/>
{/* <StatCard label="AdminInfo" value={adminInfo} /> */}
</Grid>
</Paper>
</Container>
</DialogContent>
</>
)}
{valueMintingTab === 1 && (
<>
<DialogContent
sx={{ sx={{
alignItems: 'center', position: 'relative',
display: 'flex',
flexDirection: 'column',
gap: '5px',
width: '100%',
}} }}
> >
<Button {isLoading && (
size="small" <Box
onClick={() => { sx={{
startMinting(); alignItems: 'center',
}} bottom: 0,
disabled={mintingAccounts?.length > 1} display: 'flex',
justifyContent: 'center',
left: 0,
position: 'absolute',
right: 0,
top: 0,
}}
>
<FidgetSpinner
ariaLabel="fidget-spinner-loading"
height="80"
visible={true}
width="80"
wrapperClass="fidget-spinner-wrapper"
wrapperStyle={{}}
/>
</Box>
)}
<Card
sx={{ sx={{
backgroundColor: theme.palette.other.positive, backgroundColor: theme.palette.background.default,
color: 'black', padding: '10px',
fontWeight: 'bold',
opacity: 0.7,
maxWidth: '90%',
width: '200px',
'&:hover': {
backgroundColor: theme.palette.other.positive,
color: 'black',
opacity: 1,
},
}} }}
variant="contained"
> >
{t('core:action.start_minting', {
postProcess: 'capitalizeFirstChar',
})}
</Button>
{mintingAccounts?.length > 1 && (
<Typography> <Typography>
{t('group:message.generic.minting_keys_per_node', { {t('auth:account.account_one', {
postProcess: 'capitalizeFirstChar',
})}
: {handleNames(accountInfo?.address)}
</Typography>
<Typography>
{t('core:level', {
postProcess: 'capitalizeFirstChar',
})}
: {accountInfo?.level}
</Typography>
<Typography>
{t('group:message.generic.next_level', {
postProcess: 'capitalizeFirstChar',
})}{' '}
{_levelUpBlocks()}
</Typography>
<Typography>
{t('group:message.generic.node_minting', {
postProcess: 'capitalizeFirstChar',
})}{' '}
{nodeInfos?.isMintingPossible?.toString()}
</Typography>
</Card>
<Spacer height="10px" />
{isPartOfMintingGroup && !accountIsMinting && (
<Box
sx={{
alignItems: 'center',
display: 'flex',
flexDirection: 'column',
gap: '5px',
width: '100%',
}}
>
<Button
size="small"
onClick={() => {
startMinting();
}}
disabled={mintingAccounts?.length > 1}
sx={{
backgroundColor: theme.palette.other.positive,
color: 'black',
fontWeight: 'bold',
opacity: 0.7,
maxWidth: '90%',
width: '200px',
'&:hover': {
backgroundColor: theme.palette.other.positive,
color: 'black',
opacity: 1,
},
}}
variant="contained"
>
{t('core:action.start_minting', {
postProcess: 'capitalizeFirstChar',
})}
</Button>
{mintingAccounts?.length > 1 && (
<Typography>
{t('group:message.generic.minting_keys_per_node', {
postProcess: 'capitalizeFirstChar',
})}
</Typography>
)}
</Box>
)}
<Spacer height="10px" />
{mintingAccounts?.length > 0 && (
<Typography>
{t('group:message.generic.node_minting_account', {
postProcess: 'capitalizeFirstChar', postProcess: 'capitalizeFirstChar',
})} })}
</Typography> </Typography>
)} )}
</Box> <Card
)}
<Spacer height="10px" />
{mintingAccounts?.length > 0 && (
<Typography>
{t('group:message.generic.node_minting_account', {
postProcess: 'capitalizeFirstChar',
})}
</Typography>
)}
<Card
sx={{
backgroundColor: theme.palette.background.default,
padding: '10px',
}}
>
{accountIsMinting && (
<Box
sx={{ sx={{
display: 'flex', backgroundColor: theme.palette.background.default,
gap: '5px', padding: '10px',
flexDirection: 'column',
}} }}
> >
<Typography> {accountIsMinting && (
{t('group:message.generic.node_minting_key', { <Box
postProcess: 'capitalizeFirstChar', sx={{
})} display: 'flex',
</Typography> gap: '5px',
</Box> flexDirection: 'column',
)} }}
>
<Typography>
{t('group:message.generic.node_minting_key', {
postProcess: 'capitalizeFirstChar',
})}
</Typography>
</Box>
)}
<Spacer height="10px" /> <Spacer height="10px" />
{mintingAccounts?.map((acct) => ( {mintingAccounts?.map((acct) => (
<Box <Box
key={acct?.mintingAccount} key={acct?.mintingAccount}
sx={{ sx={{
display: 'flex', display: 'flex',
gap: '10px', gap: '10px',
flexDirection: 'column', flexDirection: 'column',
}} }}
> >
<Typography> <Typography>
{t('group:message.generic.minting_account', { {t('group:message.generic.minting_account', {
postProcess: 'capitalizeFirstChar', postProcess: 'capitalizeFirstChar',
})}{' '} })}{' '}
{handleNames(acct?.mintingAccount)} {handleNames(acct?.mintingAccount)}
</Typography> </Typography>
<Button <Button
size="small" size="small"
sx={{
backgroundColor: theme.palette.other.danger,
color: theme.palette.text.primary,
fontWeight: 'bold',
maxWidth: '90%',
opacity: 0.7,
width: '200px',
'&:hover': {
backgroundColor: theme.palette.other.danger,
color: theme.palette.text.primary,
opacity: 1,
},
}}
onClick={() => {
removeMintingAccount(acct.publicKey, acct);
}}
variant="contained"
>
{t('group:action.remove_minting_account', {
postProcess: 'capitalizeFirstChar',
})}
</Button>
<Divider />
<Spacer height="10px" />
</Box>
))}
{mintingAccounts?.length > 1 && (
<Typography>
{t('group:message.generic.minting_keys_per_node_different', {
postProcess: 'capitalizeFirstChar',
})}
</Typography>
)}
</Card>
<Spacer height="20px" />
{!isPartOfMintingGroup && (
<Card
sx={{ sx={{
backgroundColor: theme.palette.other.danger, backgroundColor: theme.palette.background.default,
color: theme.palette.text.primary, padding: '10px',
fontWeight: 'bold', }}
maxWidth: '90%', >
opacity: 0.7, <Box
width: '200px', sx={{
'&:hover': { display: 'flex',
backgroundColor: theme.palette.other.danger, gap: '5px',
flexDirection: 'column',
width: '100%',
alignItems: 'center',
}}
>
<Typography>
{t('group:message.generic.minter_group', {
postProcess: 'capitalizeFirstChar',
})}
</Typography>
<Typography>
{t('group:message.generic.mintership_app', {
postProcess: 'capitalizeFirstChar',
})}
</Typography>
<Spacer height="10px" />
<Button
size="small"
sx={{
backgroundColor: theme.palette.other.positive,
color: theme.palette.text.primary,
fontWeight: 'bold',
opacity: 0.7,
'&:hover': {
backgroundColor: theme.palette.other.positive,
color: 'black',
opacity: 1,
},
}}
onClick={() => {
executeEvent('addTab', {
data: { service: 'APP', name: 'q-mintership' },
});
executeEvent('open-apps-mode', {});
setIsOpenMinting(false);
}}
variant="contained"
>
{t('group:action.visit_q_mintership', {
postProcess: 'capitalizeFirstChar',
})}
</Button>
</Box>
</Card>
)}
{showWaitDialog && (
<Dialog
open={showWaitDialog}
aria-labelledby="alert-dialog-title"
aria-describedby="alert-dialog-description"
>
<DialogTitle
id="alert-dialog-title"
sx={{
textAlign: 'center',
color: theme.palette.text.primary, color: theme.palette.text.primary,
fontWeight: 'bold',
opacity: 1, opacity: 1,
}, }}
}} >
onClick={() => { {isShowNext
removeMintingAccount(acct.publicKey, acct); ? t('core:message.generic.confirmed', {
}} postProcess: 'capitalizeFirstChar',
variant="contained" })
> : t('core:message.generic.wait', {
{t('group:action.remove_minting_account', { postProcess: 'capitalizeFirstChar',
postProcess: 'capitalizeFirstChar', })}
})} </DialogTitle>
</Button>
<Divider /> <DialogContent>
{!isShowNext && (
<Typography>
{t('group:message.success.rewardshare_creation', {
postProcess: 'capitalizeFirstChar',
})}
</Typography>
)}
<Spacer height="10px" /> {isShowNext && (
</Box> <Typography>
))} {t('group:message.success.rewardshare_confirmed', {
postProcess: 'capitalizeFirstChar',
})}
</Typography>
)}
</DialogContent>
{mintingAccounts?.length > 1 && ( <DialogActions>
<Typography> <Button
{t('group:message.generic.minting_keys_per_node_different', { disabled={!isShowNext}
postProcess: 'capitalizeFirstChar', variant="contained"
})} onClick={onOk}
</Typography> autoFocus
)} >
</Card> {t('core:page.next', {
postProcess: 'capitalizeFirstChar',
<Spacer height="20px" /> })}
</Button>
{!isPartOfMintingGroup && ( </DialogActions>
<Card </Dialog>
sx={{ )}
backgroundColor: theme.palette.background.default, </DialogContent>
padding: '10px', </>
}} )}
>
<Box
sx={{
display: 'flex',
gap: '5px',
flexDirection: 'column',
width: '100%',
alignItems: 'center',
}}
>
<Typography>
{t('group:message.generic.minter_group', {
postProcess: 'capitalizeFirstChar',
})}
</Typography>
<Typography>
{t('group:message.generic.mintership_app', {
postProcess: 'capitalizeFirstChar',
})}
</Typography>
<Spacer height="10px" />
<Button
size="small"
sx={{
backgroundColor: theme.palette.other.positive,
color: theme.palette.text.primary,
fontWeight: 'bold',
opacity: 0.7,
'&:hover': {
backgroundColor: theme.palette.other.positive,
color: 'black',
opacity: 1,
},
}}
onClick={() => {
executeEvent('addTab', {
data: { service: 'APP', name: 'q-mintership' },
});
executeEvent('open-apps-mode', {});
setIsOpenMinting(false);
}}
variant="contained"
>
{t('group:action.visit_q_mintership', {
postProcess: 'capitalizeFirstChar',
})}
</Button>
</Box>
</Card>
)}
<Container maxWidth="md" sx={{ py: 4 }}>
<Typography variant="h4" fontWeight="bold" gutterBottom>
General Minting Details
</Typography>
<Paper elevation={3} sx={{ p: 3, mb: 4, borderRadius: '10px' }}>
<Typography variant="h6" gutterBottom>
Blockchain Statistics
</Typography>
<Grid container spacing={2}>
<StatCard label="Avg. Qortal Blocktime" value="72.84 Seconds" />
<StatCard label="Avg. Blocks Per Day" value="1186.16 Blocks" />
<StatCard
label="Avg. Created QORT Per Day"
value="3558.48 QORT"
/>
</Grid>
</Paper>
<Paper elevation={3} sx={{ p: 3, mb: 4, borderRadius: '10px' }}>
<Typography variant="h6" gutterBottom>
Minting Account Details
</Typography>
<Grid container spacing={2}>
<StatCard label="Current Status" value="(Minting)" />
<StatCard label="Current Level" value="Level 4" />
<StatCard label="Blocks To Next Level" value="139467 Blocks" />
</Grid>
<Box mt={2} textAlign="center">
<Typography>
With a 24/7 Minting you will reach level 5 in{' '}
<strong>117.58 days</strong>!
</Typography>
</Box>
</Paper>
<Paper elevation={3} sx={{ p: 3, borderRadius: '10px' }}>
<Typography variant="h6" gutterBottom>
Minting Rewards Info
</Typography>
<Grid container spacing={2}>
<StatCard label="Current Tier" value="Tier 2 (Level 3 + 4)" />
<StatCard label="Total Minters in The Tier" value="77 Minters" />
<StatCard label="Tier Share Per Block" value="13%" />
<StatCard label="Est. Reward Per Block" value="0.00506494 QORT" />
<StatCard label="Est. Reward Per Day" value="6.00782338 QORT" />
{/* <StatCard label="AdminInfo" value={adminInfo} /> */}
</Grid>
</Paper>
</Container>
{showWaitDialog && (
<Dialog
open={showWaitDialog}
aria-labelledby="alert-dialog-title"
aria-describedby="alert-dialog-description"
>
<DialogTitle
id="alert-dialog-title"
sx={{
textAlign: 'center',
color: theme.palette.text.primary,
fontWeight: 'bold',
opacity: 1,
}}
>
{isShowNext
? t('core:message.generic.confirmed', {
postProcess: 'capitalizeFirstChar',
})
: t('core:message.generic.wait', {
postProcess: 'capitalizeFirstChar',
})}
</DialogTitle>
<DialogContent>
{!isShowNext && (
<Typography>
{t('group:message.success.rewardshare_creation', {
postProcess: 'capitalizeFirstChar',
})}
</Typography>
)}
{isShowNext && (
<Typography>
{t('group:message.success.rewardshare_confirmed', {
postProcess: 'capitalizeFirstChar',
})}
</Typography>
)}
</DialogContent>
<DialogActions>
<Button
disabled={!isShowNext}
variant="contained"
onClick={onOk}
autoFocus
>
{t('core:page.next', { postProcess: 'capitalizeFirstChar' })}
</Button>
</DialogActions>
</Dialog>
)}
</DialogContent>
<Snackbar <Snackbar
anchorOrigin={{ vertical: 'bottom', horizontal: 'center' }} anchorOrigin={{ vertical: 'bottom', horizontal: 'center' }}

View File

@ -207,7 +207,7 @@ export const Wallets = ({ setExtState, setRawWallet, rawWallet }) => {
if (isLoading) return null; if (isLoading) return null;
return ( return (
<div> <Box>
{wallets?.length === 0 || !wallets ? ( {wallets?.length === 0 || !wallets ? (
<> <>
<Typography> <Typography>
@ -469,7 +469,7 @@ export const Wallets = ({ setExtState, setRawWallet, rawWallet }) => {
</Typography> </Typography>
</DialogActions> </DialogActions>
</Dialog> </Dialog>
</div> </Box>
); );
}; };