added languages

This commit is contained in:
PhilReact 2025-05-21 00:35:39 +03:00
parent aa7452713f
commit e76a417f31
12 changed files with 825 additions and 94 deletions

View File

@ -82,7 +82,7 @@ const RegisterName = () => {
if (!address) return; if (!address) return;
const loadId = showLoading( const loadId = showLoading(
t('core:new_name.responses.loading', { t('core:new_name.responses.loading', {
postProcess: 'capitalize', postProcess: 'capitalizeFirstChar',
}) })
); );
try { try {
@ -114,7 +114,7 @@ const RegisterName = () => {
}); });
showSuccess( showSuccess(
t('core:new_name.responses.success', { t('core:new_name.responses.success', {
postProcess: 'capitalize', postProcess: 'capitalizeFirstChar',
}) })
); );
setNameValue(''); setNameValue('');
@ -125,7 +125,7 @@ const RegisterName = () => {
} else { } else {
showError( showError(
t('core:new_name.responses.error', { t('core:new_name.responses.error', {
postProcess: 'capitalize', postProcess: 'capitalizeFirstChar',
}) })
); );
} }
@ -191,7 +191,7 @@ const RegisterName = () => {
}} }}
> >
{t('core:actions.new_name', { {t('core:actions.new_name', {
postProcess: 'capitalize', postProcess: 'capitalizeFirstChar',
})} })}
</Button> </Button>
<Dialog <Dialog
@ -201,7 +201,7 @@ const RegisterName = () => {
> >
<DialogTitle id="alert-dialog-title"> <DialogTitle id="alert-dialog-title">
{t('core:actions.register_name', { {t('core:actions.register_name', {
postProcess: 'capitalize', postProcess: 'capitalizeFirstChar',
})} })}
</DialogTitle> </DialogTitle>
<DialogContent> <DialogContent>
@ -225,7 +225,7 @@ const RegisterName = () => {
onChange={(e) => setNameValue(e.target.value)} onChange={(e) => setNameValue(e.target.value)}
value={nameValue} value={nameValue}
placeholder={t('core:new_name.choose_name', { placeholder={t('core:new_name.choose_name', {
postProcess: 'capitalize', postProcess: 'capitalizeFirstChar',
})} })}
/> />
{(!balance || (nameFee && balance && balance < nameFee)) && ( {(!balance || (nameFee && balance && balance < nameFee)) && (
@ -247,7 +247,7 @@ const RegisterName = () => {
{t('balance_message', { {t('balance_message', {
balance: balance ?? 0, balance: balance ?? 0,
nameFee, nameFee,
postProcess: 'capitalize', postProcess: 'capitalizeFirstChar',
})} })}
</Typography> </Typography>
</Box> </Box>
@ -302,7 +302,7 @@ const RegisterName = () => {
<BarSpinner width="16px" color={theme.palette.text.primary} /> <BarSpinner width="16px" color={theme.palette.text.primary} />
<Typography> <Typography>
{t('core:new_name.checking_name', { {t('core:new_name.checking_name', {
postProcess: 'capitalize', postProcess: 'capitalizeFirstChar',
})} })}
</Typography> </Typography>
</Box> </Box>
@ -319,7 +319,7 @@ const RegisterName = () => {
}} }}
> >
{t('core:actions.close', { {t('core:actions.close', {
postProcess: 'capitalize', postProcess: 'capitalizeFirstChar',
})} })}
</Button> </Button>
<Button <Button
@ -335,7 +335,7 @@ const RegisterName = () => {
autoFocus autoFocus
> >
{t('core:actions.register_name', { {t('core:actions.register_name', {
postProcess: 'capitalize', postProcess: 'capitalizeFirstChar',
})} })}
</Button> </Button>
</DialogActions> </DialogActions>

View File

@ -24,6 +24,8 @@ import ArrowDownwardIcon from '@mui/icons-material/ArrowDownward';
import { dismissToast, showError, showLoading, showSuccess } from 'qapp-core'; import { dismissToast, showError, showLoading, showSuccess } from 'qapp-core';
import { SetStateAction } from 'jotai'; import { SetStateAction } from 'jotai';
import { SortBy, SortDirection } from '../../interfaces'; import { SortBy, SortDirection } from '../../interfaces';
import { useTranslation } from 'react-i18next';
import { TFunction } from 'i18next';
const VirtuosoTableComponents: TableComponents<NamesForSale> = { const VirtuosoTableComponents: TableComponents<NamesForSale> = {
Scroller: forwardRef<HTMLDivElement>((props, ref) => ( Scroller: forwardRef<HTMLDivElement>((props, ref) => (
@ -47,7 +49,8 @@ const VirtuosoTableComponents: TableComponents<NamesForSale> = {
function fixedHeaderContent( function fixedHeaderContent(
sortBy: string, sortBy: string,
sortDirection: string, sortDirection: string,
setSort: (field: SortBy) => void setSort: (field: SortBy) => void,
t: TFunction
) { ) {
const renderSortIcon = (field: string) => { const renderSortIcon = (field: string) => {
if (sortBy !== field) return null; if (sortBy !== field) return null;
@ -70,12 +73,18 @@ function fixedHeaderContent(
<TableRow sx={{ backgroundColor: 'background.paper' }}> <TableRow sx={{ backgroundColor: 'background.paper' }}>
<TableCell onClick={() => setSort('name')} sx={sortableCellSx}> <TableCell onClick={() => setSort('name')} sx={sortableCellSx}>
<span style={{ display: 'flex', alignItems: 'center' }}> <span style={{ display: 'flex', alignItems: 'center' }}>
Name {renderSortIcon('name')} {t('core:tables.name', {
postProcess: 'capitalizeFirstChar',
})}
{renderSortIcon('name')}
</span> </span>
</TableCell> </TableCell>
<TableCell onClick={() => setSort('salePrice')} sx={sortableCellSx}> <TableCell onClick={() => setSort('salePrice')} sx={sortableCellSx}>
<span style={{ display: 'flex', alignItems: 'center' }}> <span style={{ display: 'flex', alignItems: 'center' }}>
Sale Price {renderSortIcon('salePrice')} {t('core:market.sale_price', {
postProcess: 'capitalizeFirstChar',
})}{' '}
{renderSortIcon('salePrice')}
</span> </span>
</TableCell> </TableCell>
<TableCell>Actions</TableCell> <TableCell>Actions</TableCell>
@ -95,17 +104,26 @@ function rowContent(
setPendingTxs: SetPendingTxs, setPendingTxs: SetPendingTxs,
setNames: SetNames, setNames: SetNames,
setNamesForSale: SetNamesForSale, setNamesForSale: SetNamesForSale,
isPrimaryNameForSale: boolean isPrimaryNameForSale: boolean,
t: TFunction
) { ) {
const handleBuy = async (name: string) => { const handleBuy = async (name: string) => {
const loadId = showLoading('Attempting to purchase name...please wait'); const loadId = showLoading(
t('core:market.responses.loading', {
postProcess: 'capitalizeFirstChar',
})
);
try { try {
const res = await qortalRequest({ const res = await qortalRequest({
action: 'BUY_NAME', action: 'BUY_NAME',
nameForSale: name, nameForSale: name,
}); });
showSuccess('Purchased name'); showSuccess(
t('core:market.responses.success', {
postProcess: 'capitalizeFirstChar',
})
);
setPendingTxs((prev) => { setPendingTxs((prev) => {
return { return {
...prev, // preserve existing categories ...prev, // preserve existing categories
@ -135,7 +153,11 @@ function rowContent(
showError(error?.message); showError(error?.message);
return; return;
} }
showError('Unable to purchase name'); showError(
t('core:market.responses.error', {
postProcess: 'capitalizeFirstChar',
})
);
} finally { } finally {
dismissToast(loadId); dismissToast(loadId);
} }
@ -152,7 +174,9 @@ function rowContent(
size="small" size="small"
onClick={() => handleBuy(row.name)} onClick={() => handleBuy(row.name)}
> >
Buy {t('core:actions.buy', {
postProcess: 'capitalizeFirstChar',
})}
</Button> </Button>
</TableCell> </TableCell>
</> </>
@ -177,7 +201,7 @@ export const ForSaleTable = ({
const setNames = useSetAtom(namesAtom); const setNames = useSetAtom(namesAtom);
const setNamesForSale = useSetAtom(forSaleAtom); const setNamesForSale = useSetAtom(forSaleAtom);
const setPendingTxs = useSetAtom(pendingTxsAtom); const setPendingTxs = useSetAtom(pendingTxsAtom);
const { t } = useTranslation();
return ( return (
<Paper <Paper
sx={{ sx={{
@ -189,7 +213,7 @@ export const ForSaleTable = ({
data={namesForSale} data={namesForSale}
components={VirtuosoTableComponents} components={VirtuosoTableComponents}
fixedHeaderContent={() => fixedHeaderContent={() =>
fixedHeaderContent(sortBy, sortDirection, handleSort) fixedHeaderContent(sortBy, sortDirection, handleSort, t)
} }
itemContent={(index, row: NamesForSale) => itemContent={(index, row: NamesForSale) =>
rowContent( rowContent(
@ -198,7 +222,8 @@ export const ForSaleTable = ({
setPendingTxs, setPendingTxs,
setNames, setNames,
setNamesForSale, setNamesForSale,
isPrimaryNameForSale isPrimaryNameForSale,
t
) )
} }
/> />

View File

@ -58,6 +58,8 @@ import { usePendingTxs } from '../../hooks/useHandlePendingTxs';
import { FetchPrimaryNameType, useFetchNames } from '../../hooks/useFetchNames'; import { FetchPrimaryNameType, useFetchNames } from '../../hooks/useFetchNames';
import { Availability } from '../../interfaces'; import { Availability } from '../../interfaces';
import { SetStateAction } from 'jotai'; import { SetStateAction } from 'jotai';
import { useTranslation } from 'react-i18next';
import { TFunction } from 'i18next';
interface NameData { interface NameData {
name: string; name: string;
isSelling?: boolean; isSelling?: boolean;
@ -84,15 +86,23 @@ const VirtuosoTableComponents: TableComponents<NameData> = {
)), )),
}; };
function fixedHeaderContent() { function fixedHeaderContent(t: TFunction) {
return ( return (
<TableRow <TableRow
sx={{ sx={{
backgroundColor: 'background.paper', backgroundColor: 'background.paper',
}} }}
> >
<TableCell>Name</TableCell> <TableCell>
<TableCell>Actions</TableCell> {t('core:tables.name', {
postProcess: 'capitalizeFirstChar',
})}
</TableCell>
<TableCell>
{t('core:tables.actions', {
postProcess: 'capitalizeFirstChar',
})}
</TableCell>
</TableRow> </TableRow>
); );
} }
@ -111,7 +121,7 @@ const ManageAvatar = ({
const { setHasAvatar, getHasAvatar } = usePendingTxs(); const { setHasAvatar, getHasAvatar } = usePendingTxs();
const [refresh] = useAtom(refreshAtom); // just to subscribe const [refresh] = useAtom(refreshAtom); // just to subscribe
const [hasAvatarState, setHasAvatarState] = useState<boolean | null>(null); const [hasAvatarState, setHasAvatarState] = useState<boolean | null>(null);
const { t } = useTranslation();
const checkIfAvatarExists = useCallback( const checkIfAvatarExists = useCallback(
async (name: string) => { async (name: string) => {
try { try {
@ -160,9 +170,13 @@ const ManageAvatar = ({
{hasAvatarState === null ? ( {hasAvatarState === null ? (
<CircularProgress size={10} /> <CircularProgress size={10} />
) : hasAvatarState ? ( ) : hasAvatarState ? (
'Change avatar' t('core:actions.update_avatar', {
postProcess: 'capitalizeFirstChar',
})
) : ( ) : (
'Set avatar' t('core:actions.set_avatar', {
postProcess: 'capitalizeFirstChar',
})
)} )}
</Button> </Button>
); );
@ -186,14 +200,23 @@ function rowContent(
setPendingTxs: SetPendingTxs, setPendingTxs: SetPendingTxs,
setNames: SetNames, setNames: SetNames,
setNamesForSale: SetNamesForSale, setNamesForSale: SetNamesForSale,
isNameCurrentlyDoingATx: boolean isNameCurrentlyDoingATx: boolean,
t: TFunction
) { ) {
const handleUpdate = async (name: string) => { const handleUpdate = async (name: string) => {
if (name === primaryName && numberOfNames > 1) { if (name === primaryName && numberOfNames > 1) {
showError('Cannot update primary name while having other names'); showError(
t('core:actions.set_avatar', {
postProcess: 'capitalizeFirstChar',
})
);
return; return;
} }
const loadId = showLoading('Updating name...please wait'); const loadId = showLoading(
t('core:update_name.responses.loading', {
postProcess: 'capitalizeFirstChar',
})
);
try { try {
const response = await modalFunctionsUpdateName.show(undefined); const response = await modalFunctionsUpdateName.show(undefined);
@ -203,7 +226,11 @@ function rowContent(
newName: response, newName: response,
oldName: name, oldName: name,
}); });
showSuccess('Successfully updated name'); showSuccess(
t('core:update_name.responses.loading', {
postProcess: 'capitalizeFirstChar',
})
);
setPendingTxs((prev) => { setPendingTxs((prev) => {
return { return {
...prev, // preserve existing categories ...prev, // preserve existing categories
@ -236,7 +263,11 @@ function rowContent(
showError(error?.message); showError(error?.message);
return; return;
} }
showError('Unable to update name'); showError(
t('core:update_name.responses.loading', {
postProcess: 'capitalizeFirstChar',
})
);
console.log('error', error); console.log('error', error);
} finally { } finally {
dismissToast(loadId); dismissToast(loadId);
@ -247,23 +278,39 @@ function rowContent(
const handleSell = async (name: string) => { const handleSell = async (name: string) => {
if (name === primaryName && numberOfNames > 1) { if (name === primaryName && numberOfNames > 1) {
showError('Cannot sell primary name while having other names'); showError(
t('core:sell_name.responses.error1', {
postProcess: 'capitalizeFirstChar',
})
);
return; return;
} }
const loadId = showLoading('Placing name for sale...please wait'); const loadId = showLoading(
t('core:sell_name.responses.loading', {
postProcess: 'capitalizeFirstChar',
})
);
try { try {
if (name === primaryName) { if (name === primaryName) {
await modalFunctions.show({ name }); await modalFunctions.show({ name });
} }
const price = await modalFunctionsSellName.show(name); const price = await modalFunctionsSellName.show(name);
if (typeof price !== 'string' && typeof price !== 'number') if (typeof price !== 'string' && typeof price !== 'number')
throw new Error('Invalid price'); throw new Error(
t('core:sell_name.responses.error3', {
postProcess: 'capitalizeFirstChar',
})
);
const res = await qortalRequest({ const res = await qortalRequest({
action: 'SELL_NAME', action: 'SELL_NAME',
nameForSale: name, nameForSale: name,
salePrice: +price, salePrice: +price,
}); });
showSuccess('Placed name for sale'); showSuccess(
t('core:sell_name.responses.success', {
postProcess: 'capitalizeFirstChar',
})
);
setPendingTxs((prev) => { setPendingTxs((prev) => {
return { return {
...prev, // preserve existing categories ...prev, // preserve existing categories
@ -293,7 +340,11 @@ function rowContent(
return; return;
} }
showError('Unable to place name for sale'); showError(
t('core:sell_name.responses.error2', {
postProcess: 'capitalizeFirstChar',
})
);
console.log('error', error); console.log('error', error);
} finally { } finally {
dismissToast(loadId); dismissToast(loadId);
@ -301,7 +352,11 @@ function rowContent(
}; };
const handleCancel = async (name: string) => { const handleCancel = async (name: string) => {
const loadId = showLoading('Removing name from market...please wait'); const loadId = showLoading(
t('core:cancel_name.responses.error2', {
postProcess: 'capitalizeFirstChar',
})
);
try { try {
const res = await qortalRequest({ const res = await qortalRequest({
@ -321,18 +376,25 @@ function rowContent(
prev.filter((item) => item?.name !== res.name) prev.filter((item) => item?.name !== res.name)
); );
}, },
}, // add or overwrite this transaction },
}, },
}; };
}); });
showSuccess('Removed name from market'); showSuccess(
t('core:cancel_name.responses.error2', {
postProcess: 'capitalizeFirstChar',
})
);
} catch (error) { } catch (error) {
if (error instanceof Error) { if (error instanceof Error) {
showError(error?.message); showError(error?.message);
return; return;
} }
showError('Unable to remove name from market'); showError(
console.log('error', error); t('core:cancel_name.responses.error2', {
postProcess: 'capitalizeFirstChar',
})
);
} finally { } finally {
dismissToast(loadId); dismissToast(loadId);
} }
@ -350,7 +412,9 @@ function rowContent(
> >
{primaryName === row.name && ( {primaryName === row.name && (
<Tooltip <Tooltip
title="This is your primary name ( identity )" title={t('core:tooltips.primary_name', {
postProcess: 'capitalizeFirstChar',
})}
placement="left" placement="left"
arrow arrow
sx={{ fontSize: '24' }} sx={{ fontSize: '24' }}
@ -379,7 +443,9 @@ function rowContent(
} }
onClick={() => handleUpdate(row.name)} onClick={() => handleUpdate(row.name)}
> >
Update {t('core:actions.update', {
postProcess: 'capitalizeFirstChar',
})}
</Button> </Button>
{!row.isSelling ? ( {!row.isSelling ? (
<Button <Button
@ -392,7 +458,9 @@ function rowContent(
isNameCurrentlyDoingATx isNameCurrentlyDoingATx
} }
> >
Sell {t('core:actions.sell', {
postProcess: 'capitalizeFirstChar',
})}
</Button> </Button>
) : ( ) : (
<Button <Button
@ -401,7 +469,9 @@ function rowContent(
onClick={() => handleCancel(row.name)} onClick={() => handleCancel(row.name)}
disabled={isNameCurrentlyDoingATx} disabled={isNameCurrentlyDoingATx}
> >
Cancel Sell {t('core:actions.cancel_sell', {
postProcess: 'capitalizeFirstChar',
})}
</Button> </Button>
)} )}
<ManageAvatar <ManageAvatar
@ -424,6 +494,7 @@ export const NameTable = ({ names, primaryName }: NameTableProps) => {
const { auth } = useGlobal(); const { auth } = useGlobal();
const [namesForSale, setNamesForSale] = useAtom(forSaleAtom); const [namesForSale, setNamesForSale] = useAtom(forSaleAtom);
const [pendingTxs] = useAtom(pendingTxsAtom); const [pendingTxs] = useAtom(pendingTxsAtom);
const { t } = useTranslation(['core']);
const modalFunctions = useModal<{ name: string }>(); const modalFunctions = useModal<{ name: string }>();
const modalFunctionsUpdateName = useModal(); const modalFunctionsUpdateName = useModal();
@ -453,7 +524,7 @@ export const NameTable = ({ names, primaryName }: NameTableProps) => {
<TableVirtuoso <TableVirtuoso
data={namesToDisplay} data={namesToDisplay}
components={VirtuosoTableComponents} components={VirtuosoTableComponents}
fixedHeaderContent={fixedHeaderContent} fixedHeaderContent={() => fixedHeaderContent(t)}
itemContent={(index, row) => { itemContent={(index, row) => {
const isNameCurrentlyDoingATx = isNamePendingTx( const isNameCurrentlyDoingATx = isNamePendingTx(
row?.name, row?.name,
@ -473,7 +544,8 @@ export const NameTable = ({ names, primaryName }: NameTableProps) => {
setPendingTxs, setPendingTxs,
setNames, setNames,
setNamesForSale, setNamesForSale,
isNameCurrentlyDoingATx isNameCurrentlyDoingATx,
t
); );
}} }}
/> />
@ -483,17 +555,22 @@ export const NameTable = ({ names, primaryName }: NameTableProps) => {
aria-labelledby="alert-dialog-title" aria-labelledby="alert-dialog-title"
aria-describedby="alert-dialog-description" aria-describedby="alert-dialog-description"
> >
<DialogTitle id="alert-dialog-title">Warning</DialogTitle> <DialogTitle id="alert-dialog-title">
{t('core:warnings.warning', {
postProcess: 'capitalizeFirstChar',
})}
</DialogTitle>
<DialogContent> <DialogContent>
<DialogContentText id="alert-dialog-description"> <DialogContentText id="alert-dialog-description">
Caution when selling your primary name {t('core:warnings.primary_name_sell_caution', {
postProcess: 'capitalizeFirstChar',
})}
</DialogContentText> </DialogContentText>
<Spacer height="20px" /> <Spacer height="20px" />
<DialogContentText id="alert-dialog-description2"> <DialogContentText id="alert-dialog-description2">
{modalFunctions?.data?.name} is your primary name. If you are an {t('core:warnings.primary_name_sell', {
admin of a private group, selling this name will remove your group name: modalFunctions?.data?.name,
keys for the group. Make sure another admin re-encrypts the latest })}
keys before selling. Proceed with caution!
</DialogContentText> </DialogContentText>
</DialogContent> </DialogContent>
<DialogActions> <DialogActions>
@ -503,10 +580,14 @@ export const NameTable = ({ names, primaryName }: NameTableProps) => {
onClick={() => modalFunctions.onOk(undefined)} onClick={() => modalFunctions.onOk(undefined)}
autoFocus autoFocus
> >
continue {t('core:actions.continue', {
postProcess: 'capitalizeFirstChar',
})}
</Button> </Button>
<Button variant="contained" onClick={modalFunctions.onCancel}> <Button variant="contained" onClick={modalFunctions.onCancel}>
Cancel {t('core:actions.cancel', {
postProcess: 'capitalizeFirstChar',
})}
</Button> </Button>
</DialogActions> </DialogActions>
</Dialog> </Dialog>
@ -533,6 +614,7 @@ interface AvatarModalProps {
modalFunctionsAvatar: ModalFunctionsAvatar; modalFunctionsAvatar: ModalFunctionsAvatar;
} }
const AvatarModal = ({ modalFunctionsAvatar }: AvatarModalProps) => { const AvatarModal = ({ modalFunctionsAvatar }: AvatarModalProps) => {
const { t } = useTranslation();
const { setHasAvatar } = usePendingTxs(); const { setHasAvatar } = usePendingTxs();
const forceRefresh = useSetAtom(forceRefreshAtom); const forceRefresh = useSetAtom(forceRefreshAtom);
@ -540,10 +622,18 @@ const AvatarModal = ({ modalFunctionsAvatar }: AvatarModalProps) => {
const [isLoadingPublish, setIsLoadingPublish] = useState(false); const [isLoadingPublish, setIsLoadingPublish] = useState(false);
const publishAvatar = async () => { const publishAvatar = async () => {
const loadId = showLoading('Publishing avatar...please wait'); const loadId = showLoading(
t('core:avatar.responses.loading', {
postProcess: 'capitalizeFirstChar',
})
);
try { try {
if (!modalFunctionsAvatar?.data || !pickedAvatar?.base64) if (!modalFunctionsAvatar?.data || !pickedAvatar?.base64)
throw new Error('Missing data'); throw new Error(
t('core:avatar.responses.error1', {
postProcess: 'capitalizeFirstChar',
})
);
setIsLoadingPublish(true); setIsLoadingPublish(true);
await qortalRequest({ await qortalRequest({
action: 'PUBLISH_QDN_RESOURCE', action: 'PUBLISH_QDN_RESOURCE',
@ -555,14 +645,22 @@ const AvatarModal = ({ modalFunctionsAvatar }: AvatarModalProps) => {
setHasAvatar(modalFunctionsAvatar?.data?.name, true); setHasAvatar(modalFunctionsAvatar?.data?.name, true);
forceRefresh(); forceRefresh();
showSuccess('Successfully published avatar'); showSuccess(
t('core:avatar.responses.success', {
postProcess: 'capitalizeFirstChar',
})
);
modalFunctionsAvatar.onOk(undefined); modalFunctionsAvatar.onOk(undefined);
} catch (error) { } catch (error) {
if (error instanceof Error) { if (error instanceof Error) {
showError(error?.message); showError(error?.message);
return; return;
} }
showError('Unable to publish avatar'); showError(
t('core:avatar.responses.loading', {
postProcess: 'capitalizeFirstChar',
})
);
} finally { } finally {
dismissToast(loadId); dismissToast(loadId);
setIsLoadingPublish(false); setIsLoadingPublish(false);
@ -575,7 +673,11 @@ const AvatarModal = ({ modalFunctionsAvatar }: AvatarModalProps) => {
aria-labelledby="alert-dialog-title" aria-labelledby="alert-dialog-title"
aria-describedby="alert-dialog-description" aria-describedby="alert-dialog-description"
> >
<DialogTitle id="alert-dialog-title">Publish Avatar</DialogTitle> <DialogTitle id="alert-dialog-title">
{t('core:avatar.title', {
postProcess: 'capitalizeFirstChar',
})}
</DialogTitle>
<DialogContent <DialogContent
sx={{ sx={{
width: '300px', width: '300px',
@ -632,7 +734,11 @@ const AvatarModal = ({ modalFunctionsAvatar }: AvatarModalProps) => {
(500 KB max. for GIFS){' '} (500 KB max. for GIFS){' '}
</Typography> </Typography>
<ImagePicker onPick={(file) => setPickedAvatar(file)} mode="single"> <ImagePicker onPick={(file) => setPickedAvatar(file)} mode="single">
<Button variant="contained">Choose Image</Button> <Button variant="contained">
{t('core:actions.choose_image', {
postProcess: 'capitalizeFirstChar',
})}
</Button>
</ImagePicker> </ImagePicker>
</Box> </Box>
</DialogContent> </DialogContent>
@ -643,10 +749,14 @@ const AvatarModal = ({ modalFunctionsAvatar }: AvatarModalProps) => {
onClick={publishAvatar} onClick={publishAvatar}
autoFocus autoFocus
> >
publish {t('core:actions.publish', {
postProcess: 'capitalizeFirstChar',
})}
</Button> </Button>
<Button variant="contained" onClick={modalFunctionsAvatar.onCancel}> <Button variant="contained" onClick={modalFunctionsAvatar.onCancel}>
Cancel {t('core:actions.cancel', {
postProcess: 'capitalizeFirstChar',
})}
</Button> </Button>
</DialogActions> </DialogActions>
</Dialog> </Dialog>
@ -665,6 +775,7 @@ const UpdateNameModal = ({
const [isNameAvailable, setIsNameAvailable] = useState<Availability>( const [isNameAvailable, setIsNameAvailable] = useState<Availability>(
Availability.NULL Availability.NULL
); );
const { t } = useTranslation();
const [nameFee, setNameFee] = useState<null | number>(null); const [nameFee, setNameFee] = useState<null | number>(null);
const balance = useGlobal().auth.balance; const balance = useGlobal().auth.balance;
@ -723,16 +834,22 @@ const UpdateNameModal = ({
> >
{step === 1 && ( {step === 1 && (
<> <>
<DialogTitle id="alert-dialog-title">Warning</DialogTitle> <DialogTitle id="alert-dialog-title">
{t('core:warnings.warning', {
postProcess: 'capitalizeFirstChar',
})}
</DialogTitle>
<DialogContent> <DialogContent>
<DialogContentText id="alert-dialog-description"> <DialogContentText id="alert-dialog-description">
Caution when updating your name {t('core:update_name.title', {
postProcess: 'capitalizeFirstChar',
})}
</DialogContentText> </DialogContentText>
<Spacer height="20px" /> <Spacer height="20px" />
<DialogContentText id="alert-dialog-description2"> <DialogContentText id="alert-dialog-description2">
If you update your Name, you will forfeit the resources associated {t('core:warnings.update_name1', {
with the original Name. In other words, you will lose ownership of postProcess: 'capitalizeFirstChar',
the content under the original Name on QDN. Proceed with caution! })}
</DialogContentText> </DialogContentText>
</DialogContent> </DialogContent>
<DialogActions> <DialogActions>
@ -742,23 +859,33 @@ const UpdateNameModal = ({
onClick={() => setStep(2)} onClick={() => setStep(2)}
autoFocus autoFocus
> >
continue {t('core:actions.continue', {
postProcess: 'capitalizeFirstChar',
})}
</Button> </Button>
<Button <Button
variant="contained" variant="contained"
onClick={modalFunctionsUpdateName.onCancel} onClick={modalFunctionsUpdateName.onCancel}
> >
Cancel {t('core:actions.cancel', {
postProcess: 'capitalizeFirstChar',
})}
</Button> </Button>
</DialogActions> </DialogActions>
</> </>
)} )}
{step === 2 && ( {step === 2 && (
<> <>
<DialogTitle id="alert-dialog-title">Warning</DialogTitle> <DialogTitle id="alert-dialog-title">
{t('core:warnings.warning', {
postProcess: 'capitalizeFirstChar',
})}
</DialogTitle>
<DialogContent> <DialogContent>
<DialogContentText id="alert-dialog-description"> <DialogContentText id="alert-dialog-description">
Choose new name {t('core:update_name.choose_name', {
postProcess: 'capitalizeFirstChar',
})}
</DialogContentText> </DialogContentText>
<Spacer height="20px" /> <Spacer height="20px" />
<TextField <TextField
@ -766,7 +893,9 @@ const UpdateNameModal = ({
autoFocus autoFocus
onChange={(e) => setNewName(e.target.value)} onChange={(e) => setNewName(e.target.value)}
value={newName} value={newName}
placeholder="Choose a name" placeholder={t('core:new_name.choose_name', {
postProcess: 'capitalizeFirstChar',
})}
/> />
{(!balance || (nameFee && balance && balance < nameFee)) && ( {(!balance || (nameFee && balance && balance < nameFee)) && (
<> <>
@ -784,8 +913,11 @@ const UpdateNameModal = ({
}} }}
/> />
<Typography> <Typography>
Your balance is {balance ?? 0} QORT. A name registration {t('core:update_name.balanceInfo', {
requires a {nameFee} QORT fee postProcess: 'capitalizeFirstChar',
nameFee: nameFee,
balance: balance ?? 0,
})}
</Typography> </Typography>
</Box> </Box>
<Spacer height="10px" /> <Spacer height="10px" />
@ -805,7 +937,12 @@ const UpdateNameModal = ({
color: theme.palette.text.primary, color: theme.palette.text.primary,
}} }}
/> />
<Typography>{newName} is available</Typography> <Typography>
{' '}
{t('core:update_name.name_available', {
name: newName,
})}
</Typography>
</Box> </Box>
)} )}
{isNameAvailable === Availability.NOT_AVAILABLE && ( {isNameAvailable === Availability.NOT_AVAILABLE && (
@ -821,7 +958,11 @@ const UpdateNameModal = ({
color: theme.palette.text.primary, color: theme.palette.text.primary,
}} }}
/> />
<Typography>{newName} is unavailable</Typography> <Typography>
{t('core:update_name.name_unavailable', {
name: newName,
})}
</Typography>
</Box> </Box>
)} )}
{isNameAvailable === Availability.LOADING && ( {isNameAvailable === Availability.LOADING && (
@ -833,7 +974,11 @@ const UpdateNameModal = ({
}} }}
> >
<BarSpinner width="16px" color={theme.palette.text.primary} /> <BarSpinner width="16px" color={theme.palette.text.primary} />
<Typography>Checking if name already existis</Typography> <Typography>
{t('core:new_name.checking', {
postProcess: 'capitalizeFirstChar',
})}
</Typography>
</Box> </Box>
)} )}
</DialogContent> </DialogContent>
@ -850,14 +995,18 @@ const UpdateNameModal = ({
onClick={() => modalFunctionsUpdateName.onOk(newName.trim())} onClick={() => modalFunctionsUpdateName.onOk(newName.trim())}
autoFocus autoFocus
> >
continue {t('core:actions.continue', {
postProcess: 'capitalizeFirstChar',
})}
</Button> </Button>
<Button <Button
color="secondary" color="secondary"
variant="contained" variant="contained"
onClick={modalFunctionsUpdateName.onCancel} onClick={modalFunctionsUpdateName.onCancel}
> >
Cancel {t('core:actions.cancel', {
postProcess: 'capitalizeFirstChar',
})}
</Button> </Button>
</DialogActions> </DialogActions>
</> </>
@ -871,6 +1020,7 @@ interface SellNameModalProps {
} }
const SellNameModal = ({ modalFunctionsSellName }: SellNameModalProps) => { const SellNameModal = ({ modalFunctionsSellName }: SellNameModalProps) => {
const { t } = useTranslation();
const [price, setPrice] = useState(0); const [price, setPrice] = useState(0);
return ( return (
@ -879,10 +1029,16 @@ const SellNameModal = ({ modalFunctionsSellName }: SellNameModalProps) => {
aria-labelledby="alert-dialog-title" aria-labelledby="alert-dialog-title"
aria-describedby="alert-dialog-description" aria-describedby="alert-dialog-description"
> >
<DialogTitle id="alert-dialog-title">Selling name</DialogTitle> <DialogTitle id="alert-dialog-title">
{t('core:sell_name.title', {
postProcess: 'capitalizeFirstChar',
})}
</DialogTitle>
<DialogContent> <DialogContent>
<DialogContentText id="alert-dialog-description"> <DialogContentText id="alert-dialog-description">
Choose selling price {t('core:sell_name.choose_price', {
postProcess: 'capitalizeFirstChar',
})}
</DialogContentText> </DialogContentText>
<Spacer height="20px" /> <Spacer height="20px" />
<TextField <TextField
@ -891,7 +1047,9 @@ const SellNameModal = ({ modalFunctionsSellName }: SellNameModalProps) => {
onChange={(e) => setPrice(+e.target.value)} onChange={(e) => setPrice(+e.target.value)}
value={price} value={price}
type="number" type="number"
placeholder="Choose a name" placeholder={t('core:new_name.choose_price', {
postProcess: 'capitalizeFirstChar',
})}
/> />
</DialogContent> </DialogContent>
<DialogActions> <DialogActions>
@ -902,14 +1060,18 @@ const SellNameModal = ({ modalFunctionsSellName }: SellNameModalProps) => {
onClick={() => modalFunctionsSellName.onOk(price)} onClick={() => modalFunctionsSellName.onOk(price)}
autoFocus autoFocus
> >
continue {t('core:actions.continue', {
postProcess: 'capitalizeFirstChar',
})}
</Button> </Button>
<Button <Button
color="secondary" color="secondary"
variant="contained" variant="contained"
onClick={modalFunctionsSellName.onCancel} onClick={modalFunctionsSellName.onCancel}
> >
Cancel {t('core:actions.cancel', {
postProcess: 'capitalizeFirstChar',
})}
</Button> </Button>
</DialogActions> </DialogActions>
</Dialog> </Dialog>

View File

@ -0,0 +1,96 @@
{
"header": {
"my_names": "meine Namen",
"market": "Namen zum Verkauf"
},
"inputs": {
"filter_names": "Namen filtern"
},
"actions": {
"new_name": "neuer Name",
"register_name": "Name registrieren",
"close": "schließen",
"update_avatar": "Avatar aktualisieren",
"set_avatar": "Avatar festlegen",
"update": "aktualisieren",
"sell": "verkaufen",
"cancel_sell": "Verkauf abbrechen",
"cancel": "abbrechen",
"continue": "fortfahren",
"publish": "veröffentlichen",
"buy": "kaufen",
"choose_image": "Bild auswählen"
},
"new_name": {
"choose_name": "wähle einen Namen",
"balance_message": "Dein Guthaben beträgt {{balance}} QORT. Die Registrierung eines Namens kostet eine Gebühr von {{nameFee}} QORT.",
"name_available": "{{name}} ist verfügbar",
"name_unavailable": "{{name}} ist nicht verfügbar",
"checking_name": "überprüfe, ob der Name bereits existiert",
"responses": {
"success": "Name erfolgreich registriert",
"error": "Name konnte nicht registriert werden",
"loading": "Name wird registriert... bitte warten"
}
},
"tables": {
"name": "Name",
"actions": "Aktionen"
},
"update_name": {
"responses": {
"loading": "Name wird aktualisiert... bitte warten",
"success": "Name erfolgreich aktualisiert",
"error": "Name konnte nicht aktualisiert werden"
},
"title": "Vorsicht beim Aktualisieren deines Namens",
"choose_name": "neuen Namen wählen",
"balance_info": "Dein Guthaben beträgt {{balance}} QORT. Die Registrierung eines Namens kostet eine Gebühr von {{nameFee}} QORT.",
"name_available": "{{name}} ist verfügbar",
"name_unavailable": "{{name}} ist nicht verfügbar"
},
"sell_name": {
"responses": {
"loading": "Name wird zum Verkauf angeboten... bitte warten",
"success": "Name zum Verkauf angeboten",
"error1": "Primärname kann nicht verkauft werden, solange andere Namen vorhanden sind",
"error2": "Name konnte nicht zum Verkauf angeboten werden",
"error3": "ungültiger Preis"
},
"title": "Name verkaufen",
"choose_price": "Verkaufspreis festlegen"
},
"cancel_name": {
"responses": {
"loading": "Name wird vom Markt entfernt... bitte warten",
"success": "Name vom Markt entfernt",
"error": "Name konnte nicht vom Markt entfernt werden"
}
},
"tooltips": {
"primary_name": "dies ist dein Primärname (Identität)"
},
"warnings": {
"warning": "Warnung",
"primary_name_sell_caution": "Vorsicht beim Verkauf deines Primärnamens",
"primary_name_sell": "{{name}} ist dein Primärname. Wenn du Administrator einer privaten Gruppe bist, wird durch den Verkauf dieses Namens dein Gruppenschlüssel entfernt. Stelle sicher, dass ein anderer Administrator die neuesten Schlüssel neu verschlüsselt, bevor du verkaufst. Bitte mit Vorsicht fortfahren!",
"update_name1": "Wenn du deinen Namen aktualisierst, verlierst du die mit dem ursprünglichen Namen verbundenen Ressourcen. Anders gesagt: Du verlierst den Besitz der Inhalte unter dem ursprünglichen Namen im QDN. Bitte mit Vorsicht fortfahren!"
},
"avatar": {
"responses": {
"loading": "Avatar wird veröffentlicht... bitte warten",
"success": "Avatar erfolgreich veröffentlicht",
"error1": "fehlende Daten",
"error2": "Avatar konnte nicht veröffentlicht werden"
},
"title": "Avatar veröffentlichen"
},
"market": {
"sale_price": "Verkaufspreis",
"responses": {
"loading": "versuche, Namen zu kaufen... bitte warten",
"success": "Name erfolgreich gekauft",
"error": "Name konnte nicht gekauft werden"
}
}
}

View File

@ -9,7 +9,17 @@
"actions": { "actions": {
"new_name": "new name", "new_name": "new name",
"register_name": "register name", "register_name": "register name",
"close": "close" "close": "close",
"update_avatar": "update avatar",
"set_avatar": "set avatar",
"update": "update",
"sell": "sell",
"cancel_sell": "cancel sell",
"cancel": "cancel",
"continue": "continue",
"publish": "publish",
"buy": "buy",
"choose_image": "choose Image"
}, },
"new_name": { "new_name": {
"choose_name": "choose a name", "choose_name": "choose a name",
@ -18,9 +28,69 @@
"name_unavailable": "{{name}} is unavailable", "name_unavailable": "{{name}} is unavailable",
"checking_name": "checking if name already exists", "checking_name": "checking if name already exists",
"responses": { "responses": {
"success": "successfully registered a name", "success": "successfully registered the name",
"error": "unable to register name", "error": "unable to register name",
"loading": "Registering name...please wait" "loading": "registering name... please wait"
}
},
"tables": {
"name": "name",
"actions": "actions"
},
"update_name": {
"responses": {
"loading": "updating name... please wait",
"success": "successfully updated name",
"error": "unable to update name"
},
"title": "caution when updating your name",
"choose_name": "choose new name",
"balance_info": "Your balance is {{balance}} QORT. A name registration requires a {{nameFee}} QORT fee.",
"name_available": "{{name}} is available",
"name_unavailable": "{{name}} is unavailable"
},
"sell_name": {
"responses": {
"loading": "placing name for sale... please wait",
"success": "placed name for sale",
"error1": "cannot sell primary name while having other names",
"error2": "unable to place name for sale",
"error3": "invalid price"
},
"title": "selling name",
"choose_price": "choose selling price"
},
"cancel_name": {
"responses": {
"loading": "removing name from market... please wait",
"success": "removed name from market",
"error": "unable to remove name from market"
}
},
"tooltips": {
"primary_name": "this is your primary name (identity)"
},
"warnings": {
"warning": "warning",
"primary_name_sell_caution": "caution when selling your primary name",
"primary_name_sell": "{{name}} is your primary name. If you are an admin of a private group, selling this name will remove your group keys for the group. Make sure another admin re-encrypts the latest keys before selling. Proceed with caution!",
"update_name1": "if you update your Name, you will forfeit the resources associated with the original Name. In other words, you will lose ownership of the content under the original Name on QDN. Proceed with caution!"
},
"avatar": {
"responses": {
"loading": "publishing avatar... please wait",
"success": "successfully published avatar",
"error1": "missing data",
"error2": "Unable to publish avatar"
},
"title": "publish avatar"
},
"market": {
"sale_price": "sale price",
"responses": {
"loading": "attempting to purchase name... please wait",
"success": "purchased name",
"error": "unable to purchase name"
} }
} }
} }

View File

@ -1,6 +1,96 @@
{ {
"header": { "header": {
"my_names": "mis nombres", "my_names": "mis nombres",
"market": "" "market": "nombres en venta"
},
"inputs": {
"filter_names": "filtrar nombres"
},
"actions": {
"new_name": "nuevo nombre",
"register_name": "registrar nombre",
"close": "cerrar",
"update_avatar": "actualizar avatar",
"set_avatar": "establecer avatar",
"update": "actualizar",
"sell": "vender",
"cancel_sell": "cancelar venta",
"cancel": "cancelar",
"continue": "continuar",
"publish": "publicar",
"buy": "comprar",
"choose_image": "elegir imagen"
},
"new_name": {
"choose_name": "elige un nombre",
"balance_message": "Tu saldo es {{balance}} QORT. Registrar un nombre requiere una tarifa de {{nameFee}} QORT.",
"name_available": "{{name}} está disponible",
"name_unavailable": "{{name}} no está disponible",
"checking_name": "verificando si el nombre ya existe",
"responses": {
"success": "nombre registrado con éxito",
"error": "no se pudo registrar el nombre",
"loading": "registrando nombre... por favor espera"
}
},
"tables": {
"name": "nombre",
"actions": "acciones"
},
"update_name": {
"responses": {
"loading": "actualizando nombre... por favor espera",
"success": "nombre actualizado con éxito",
"error": "no se pudo actualizar el nombre"
},
"title": "precaución al actualizar tu nombre",
"choose_name": "elige un nuevo nombre",
"balance_info": "Tu saldo es {{balance}} QORT. Registrar un nombre requiere una tarifa de {{nameFee}} QORT.",
"name_available": "{{name}} está disponible",
"name_unavailable": "{{name}} no está disponible"
},
"sell_name": {
"responses": {
"loading": "poniendo el nombre a la venta... por favor espera",
"success": "nombre puesto a la venta",
"error1": "no puedes vender el nombre principal si tienes otros nombres",
"error2": "no se pudo poner el nombre a la venta",
"error3": "precio inválido"
},
"title": "vender nombre",
"choose_price": "elige el precio de venta"
},
"cancel_name": {
"responses": {
"loading": "eliminando nombre del mercado... por favor espera",
"success": "nombre eliminado del mercado",
"error": "no se pudo eliminar el nombre del mercado"
}
},
"tooltips": {
"primary_name": "este es tu nombre principal (identidad)"
},
"warnings": {
"warning": "advertencia",
"primary_name_sell_caution": "precaución al vender tu nombre principal",
"primary_name_sell": "{{name}} es tu nombre principal. Si eres administrador de un grupo privado, vender este nombre eliminará tus claves de grupo. Asegúrate de que otro administrador vuelva a cifrar las últimas claves antes de vender. ¡Procede con precaución!",
"update_name1": "si actualizas tu nombre, perderás los recursos asociados con el nombre original. En otras palabras, perderás la propiedad del contenido bajo el nombre original en QDN. ¡Procede con precaución!"
},
"avatar": {
"responses": {
"loading": "publicando avatar... por favor espera",
"success": "avatar publicado con éxito",
"error1": "faltan datos",
"error2": "no se pudo publicar el avatar"
},
"title": "publicar avatar"
},
"market": {
"sale_price": "precio de venta",
"responses": {
"loading": "intentando comprar nombre... por favor espera",
"success": "nombre comprado",
"error": "no se pudo comprar el nombre"
}
} }
} }

View File

@ -0,0 +1,96 @@
{
"header": {
"my_names": "mes noms",
"market": "noms en vente"
},
"inputs": {
"filter_names": "filtrer les noms"
},
"actions": {
"new_name": "nouveau nom",
"register_name": "enregistrer le nom",
"close": "fermer",
"update_avatar": "mettre à jour l'avatar",
"set_avatar": "définir l'avatar",
"update": "mettre à jour",
"sell": "vendre",
"cancel_sell": "annuler la vente",
"cancel": "annuler",
"continue": "continuer",
"publish": "publier",
"buy": "acheter",
"choose_image": "choisir une image"
},
"new_name": {
"choose_name": "choisissez un nom",
"balance_message": "Votre solde est de {{balance}} QORT. Lenregistrement dun nom nécessite des frais de {{nameFee}} QORT.",
"name_available": "{{name}} est disponible",
"name_unavailable": "{{name}} nest pas disponible",
"checking_name": "vérification de lexistence du nom",
"responses": {
"success": "nom enregistré avec succès",
"error": "impossible d'enregistrer le nom",
"loading": "enregistrement du nom... veuillez patienter"
}
},
"tables": {
"name": "nom",
"actions": "actions"
},
"update_name": {
"responses": {
"loading": "mise à jour du nom... veuillez patienter",
"success": "nom mis à jour avec succès",
"error": "impossible de mettre à jour le nom"
},
"title": "attention lors de la mise à jour de votre nom",
"choose_name": "choisir un nouveau nom",
"balance_info": "Votre solde est de {{balance}} QORT. Lenregistrement dun nom nécessite des frais de {{nameFee}} QORT.",
"name_available": "{{name}} est disponible",
"name_unavailable": "{{name}} nest pas disponible"
},
"sell_name": {
"responses": {
"loading": "mise en vente du nom... veuillez patienter",
"success": "nom mis en vente",
"error1": "impossible de vendre le nom principal si d'autres noms existent",
"error2": "impossible de mettre le nom en vente",
"error3": "prix invalide"
},
"title": "vendre un nom",
"choose_price": "choisissez un prix de vente"
},
"cancel_name": {
"responses": {
"loading": "retrait du nom du marché... veuillez patienter",
"success": "nom retiré du marché",
"error": "impossible de retirer le nom du marché"
}
},
"tooltips": {
"primary_name": "il s'agit de votre nom principal (identité)"
},
"warnings": {
"warning": "avertissement",
"primary_name_sell_caution": "prudence lors de la vente de votre nom principal",
"primary_name_sell": "{{name}} est votre nom principal. Si vous êtes administrateur dun groupe privé, la vente de ce nom supprimera vos clés de groupe. Assurez-vous quun autre administrateur chiffre à nouveau les dernières clés avant de vendre. Procédez avec prudence !",
"update_name1": "si vous mettez à jour votre nom, vous perdrez les ressources associées au nom dorigine. En d'autres termes, vous perdrez la propriété du contenu lié à l'ancien nom sur QDN. Procédez avec prudence !"
},
"avatar": {
"responses": {
"loading": "publication de l'avatar... veuillez patienter",
"success": "avatar publié avec succès",
"error1": "données manquantes",
"error2": "impossible de publier l'avatar"
},
"title": "publier l'avatar"
},
"market": {
"sale_price": "prix de vente",
"responses": {
"loading": "tentative d'achat du nom... veuillez patienter",
"success": "nom acheté avec succès",
"error": "impossible dacheter le nom"
}
}
}

View File

@ -0,0 +1,96 @@
{
"header": {
"my_names": "i miei nomi",
"market": "nomi in vendita"
},
"inputs": {
"filter_names": "filtra nomi"
},
"actions": {
"new_name": "nuovo nome",
"register_name": "registrare nome",
"close": "chiudi",
"update_avatar": "aggiorna avatar",
"set_avatar": "imposta avatar",
"update": "aggiorna",
"sell": "vendi",
"cancel_sell": "annulla vendita",
"cancel": "annulla",
"continue": "continua",
"publish": "pubblica",
"buy": "acquista",
"choose_image": "scegli immagine"
},
"new_name": {
"choose_name": "scegli un nome",
"balance_message": "Il tuo saldo è {{balance}} QORT. La registrazione di un nome richiede una commissione di {{nameFee}} QORT.",
"name_available": "{{name}} è disponibile",
"name_unavailable": "{{name}} non è disponibile",
"checking_name": "verifica se il nome esiste già",
"responses": {
"success": "nome registrato con successo",
"error": "impossibile registrare il nome",
"loading": "registrazione del nome... attendere"
}
},
"tables": {
"name": "nome",
"actions": "azioni"
},
"update_name": {
"responses": {
"loading": "aggiornamento del nome... attendere",
"success": "nome aggiornato con successo",
"error": "impossibile aggiornare il nome"
},
"title": "attenzione durante l'aggiornamento del nome",
"choose_name": "scegli un nuovo nome",
"balance_info": "Il tuo saldo è {{balance}} QORT. La registrazione di un nome richiede una commissione di {{nameFee}} QORT.",
"name_available": "{{name}} è disponibile",
"name_unavailable": "{{name}} non è disponibile"
},
"sell_name": {
"responses": {
"loading": "messa in vendita del nome... attendere",
"success": "nome messo in vendita",
"error1": "non puoi vendere il nome principale se hai altri nomi",
"error2": "impossibile mettere il nome in vendita",
"error3": "prezzo non valido"
},
"title": "vendere nome",
"choose_price": "scegli il prezzo di vendita"
},
"cancel_name": {
"responses": {
"loading": "rimozione del nome dal mercato... attendere",
"success": "nome rimosso dal mercato",
"error": "impossibile rimuovere il nome dal mercato"
}
},
"tooltips": {
"primary_name": "questo è il tuo nome principale (identità)"
},
"warnings": {
"warning": "avviso",
"primary_name_sell_caution": "attenzione alla vendita del nome principale",
"primary_name_sell": "{{name}} è il tuo nome principale. Se sei amministratore di un gruppo privato, la vendita di questo nome rimuoverà le chiavi del gruppo. Assicurati che un altro amministratore re-critti le chiavi più recenti prima di vendere. Procedi con cautela!",
"update_name1": "se aggiorni il tuo nome, perderai le risorse associate al nome originale. In altre parole, perderai la proprietà dei contenuti collegati al nome originale su QDN. Procedi con cautela!"
},
"avatar": {
"responses": {
"loading": "pubblicazione dell'avatar... attendere",
"success": "avatar pubblicato con successo",
"error1": "dati mancanti",
"error2": "impossibile pubblicare l'avatar"
},
"title": "pubblica avatar"
},
"market": {
"sale_price": "prezzo di vendita",
"responses": {
"loading": "tentativo di acquisto del nome... attendere",
"success": "nome acquistato con successo",
"error": "impossibile acquistare il nome"
}
}
}

View File

@ -0,0 +1,96 @@
{
"header": {
"my_names": "мои имена",
"market": "имена на продажу"
},
"inputs": {
"filter_names": "фильтровать имена"
},
"actions": {
"new_name": "новое имя",
"register_name": "зарегистрировать имя",
"close": "закрыть",
"update_avatar": "обновить аватар",
"set_avatar": "установить аватар",
"update": "обновить",
"sell": "продать",
"cancel_sell": "отменить продажу",
"cancel": "отмена",
"continue": "продолжить",
"publish": "опубликовать",
"buy": "купить",
"choose_image": "выбрать изображение"
},
"new_name": {
"choose_name": "выберите имя",
"balance_message": "Ваш баланс: {{balance}} QORT. Регистрация имени требует комиссии в размере {{nameFee}} QORT.",
"name_available": "{{name}} доступно",
"name_unavailable": "{{name}} недоступно",
"checking_name": "проверка существования имени",
"responses": {
"success": "имя успешно зарегистрировано",
"error": "не удалось зарегистрировать имя",
"loading": "регистрация имени... пожалуйста, подождите"
}
},
"tables": {
"name": "имя",
"actions": "действия"
},
"update_name": {
"responses": {
"loading": "обновление имени... пожалуйста, подождите",
"success": "имя успешно обновлено",
"error": "не удалось обновить имя"
},
"title": "внимание при обновлении имени",
"choose_name": "выберите новое имя",
"balance_info": "Ваш баланс: {{balance}} QORT. Регистрация имени требует комиссии в размере {{nameFee}} QORT.",
"name_available": "{{name}} доступно",
"name_unavailable": "{{name}} недоступно"
},
"sell_name": {
"responses": {
"loading": "выставление имени на продажу... пожалуйста, подождите",
"success": "имя выставлено на продажу",
"error1": "нельзя продавать основное имя при наличии других имён",
"error2": "не удалось выставить имя на продажу",
"error3": "некорректная цена"
},
"title": "продажа имени",
"choose_price": "укажите цену продажи"
},
"cancel_name": {
"responses": {
"loading": "удаление имени с рынка... пожалуйста, подождите",
"success": "имя удалено с рынка",
"error": "не удалось удалить имя с рынка"
}
},
"tooltips": {
"primary_name": "это ваше основное имя (идентификатор)"
},
"warnings": {
"warning": "предупреждение",
"primary_name_sell_caution": "осторожно при продаже основного имени",
"primary_name_sell": "{{name}} — это ваше основное имя. Если вы администратор частной группы, продажа этого имени приведет к удалению ваших ключей группы. Убедитесь, что другой администратор заново зашифрует последние ключи перед продажей. Действуйте с осторожностью!",
"update_name1": "если вы обновите имя, вы потеряете ресурсы, связанные с исходным именем. Иными словами, вы утратите право собственности на контент, размещённый под исходным именем в QDN. Действуйте с осторожностью!"
},
"avatar": {
"responses": {
"loading": "публикация аватара... пожалуйста, подождите",
"success": "аватар успешно опубликован",
"error1": "отсутствуют данные",
"error2": "не удалось опубликовать аватар"
},
"title": "опубликовать аватар"
},
"market": {
"sale_price": "цена продажи",
"responses": {
"loading": "попытка покупки имени... пожалуйста, подождите",
"success": "имя успешно куплено",
"error": "не удалось купить имя"
}
}
}

View File

@ -110,7 +110,7 @@ export const Market = () => {
> >
<TextField <TextField
placeholder={t('core:inputs.filter_names', { placeholder={t('core:inputs.filter_names', {
postProcess: 'capitalize', postProcess: 'capitalizeFirstChar',
})} })}
value={value} value={value}
onChange={(e) => setValue(e.target.value)} onChange={(e) => setValue(e.target.value)}

View File

@ -54,7 +54,7 @@ export const MyNames = () => {
{' '} {' '}
<TextField <TextField
placeholder={t('core:inputs.filter_names', { placeholder={t('core:inputs.filter_names', {
postProcess: 'capitalize', postProcess: 'capitalizeFirstChar',
})} })}
value={value} value={value}
onChange={(e) => setValue(e.target.value)} onChange={(e) => setValue(e.target.value)}

View File

@ -15,12 +15,12 @@ const Layout = () => {
const navItems = [ const navItems = [
{ {
label: t('core:header.my_names', { postProcess: 'capitalize' }), label: t('core:header.my_names', { postProcess: 'capitalizeFirstChar' }),
path: '/', path: '/',
Icon: FormatListBulletedIcon, Icon: FormatListBulletedIcon,
}, },
{ {
label: t('core:header.market', { postProcess: 'capitalize' }), label: t('core:header.market', { postProcess: 'capitalizeFirstChar' }),
path: '/market', path: '/market',
Icon: StorefrontIcon, Icon: StorefrontIcon,
}, },