i18n for welcome page

This commit is contained in:
Nicola Benaglia 2025-04-21 21:02:10 +02:00
parent 7f97f2972a
commit 59573a43ab
6 changed files with 299 additions and 287 deletions

View File

@ -6,6 +6,12 @@
"description": "description", "description": "description",
"edit": "edit", "edit": "edit",
"error": "an error occurred", "error": "an error occurred",
"last_height": "last height",
"price": "price",
"save": "save", "save": "save",
"title": "title" "supply": "supply",
"title": "title",
"wallet": "wallet",
"wallet_many": "wallets",
"welcome": "welcome"
} }

View File

@ -11,7 +11,11 @@
}, },
"initial": { "initial": {
"6_qort": "Have at least 6 QORT in your wallet", "6_qort": "Have at least 6 QORT in your wallet",
"explore": "explore",
"general_chat": "general chat",
"getting_started": "getting started", "getting_started": "getting started",
"register_name": "register a name" "register_name": "register a name",
"see_apps": "see apps",
"trade_qort": "trade QORT"
} }
} }

View File

@ -6,7 +6,8 @@
"description": "descrizione", "description": "descrizione",
"edit": "modifica", "edit": "modifica",
"error": "si è verificato un errore", "error": "si è verificato un errore",
"loading": "loading...", "loading": "caricamento...",
"save": "salva", "save": "salva",
"supply": "offerta",
"title": "titolo" "title": "titolo"
} }

View File

@ -1,129 +1,130 @@
import { Box, ButtonBase, Typography } from "@mui/material"; import { Box, ButtonBase, Typography, useTheme } from '@mui/material';
import React from "react"; import ChatIcon from '@mui/icons-material/Chat';
import ChatIcon from "@mui/icons-material/Chat"; import qTradeLogo from '../../assets/Icons/q-trade-logo.webp';
import qTradeLogo from "../../assets/Icons/q-trade-logo.webp"; import AppsIcon from '@mui/icons-material/Apps';
import AppsIcon from "@mui/icons-material/Apps"; import { executeEvent } from '../../utils/events';
import { executeEvent } from "../../utils/events";
import AccountBalanceWalletIcon from '@mui/icons-material/AccountBalanceWallet'; import AccountBalanceWalletIcon from '@mui/icons-material/AccountBalanceWallet';
import { useTranslation } from 'react-i18next';
export const Explore = ({ setDesktopViewMode }) => {
const theme = useTheme();
const { t } = useTranslation(['core', 'tutorial']);
export const Explore = ({setDesktopViewMode}) => {
return ( return (
<Box <Box
sx={{ sx={{
display: "flex", display: 'flex',
gap: "20px", gap: '20px',
flexWrap: "wrap", flexWrap: 'wrap',
}} }}
> >
<ButtonBase <ButtonBase
sx={{ sx={{
"&:hover": { backgroundColor: "secondary.main" }, '&:hover': { backgroundColor: theme.palette.background.paper },
transition: "all 0.1s ease-in-out", borderRadius: '5px',
padding: "5px", gap: '5px',
borderRadius: "5px", padding: '5px',
gap: "5px", transition: 'all 0.1s ease-in-out',
}} }}
onClick={async () => { onClick={async () => {
executeEvent("addTab", { executeEvent('addTab', {
data: { service: "APP", name: "q-trade" }, data: { service: 'APP', name: 'q-trade' },
}); });
executeEvent("open-apps-mode", {}); executeEvent('open-apps-mode', {});
}} }}
> >
<img <img
style={{ style={{
borderRadius: "50%", borderRadius: '50%',
height: '30px' height: '30px',
}} }}
src={qTradeLogo} src={qTradeLogo}
/> />
<Typography <Typography
sx={{ sx={{
fontSize: "1rem", fontSize: '1rem',
}} }}
> >
Trade QORT {t('tutorial:initial.trade_qort', { postProcess: 'capitalize' })}
</Typography> </Typography>
</ButtonBase> </ButtonBase>
<ButtonBase <ButtonBase
sx={{ sx={{
"&:hover": { backgroundColor: "secondary.main" }, '&:hover': { backgroundColor: theme.palette.background.paper },
transition: "all 0.1s ease-in-out", borderRadius: '5px',
padding: "5px", gap: '5px',
borderRadius: "5px", padding: '5px',
gap: "5px", transition: 'all 0.1s ease-in-out',
}}
onClick={() => {
setDesktopViewMode('apps');
}} }}
onClick={()=> {
setDesktopViewMode('apps')
}}
> >
<AppsIcon <AppsIcon
sx={{ sx={{
color: "white", color: theme.palette.text.primary,
}} }}
/> />
<Typography <Typography
sx={{ sx={{
fontSize: "1rem", fontSize: '1rem',
}} }}
> >
See Apps {t('tutorial:initial.see_apps', { postProcess: 'capitalize' })}
</Typography> </Typography>
</ButtonBase> </ButtonBase>
<ButtonBase <ButtonBase
sx={{ sx={{
"&:hover": { backgroundColor: "secondary.main" }, '&:hover': { backgroundColor: theme.palette.background.paper },
transition: "all 0.1s ease-in-out", borderRadius: '5px',
padding: "5px", gap: '5px',
borderRadius: "5px", padding: '5px',
gap: "5px", transition: 'all 0.1s ease-in-out',
}} }}
onClick={async () => { onClick={async () => {
executeEvent("openGroupMessage", { executeEvent('openGroupMessage', {
from: "0" , from: '0',
}); });
}} }}
> >
<ChatIcon <ChatIcon
sx={{ sx={{
color: "white", color: theme.palette.text.primary,
}} }}
/> />
<Typography <Typography
sx={{ sx={{
fontSize: "1rem", fontSize: '1rem',
}} }}
> >
General Chat {t('tutorial:initial.general_chat', { postProcess: 'capitalize' })}
</Typography> </Typography>
</ButtonBase> </ButtonBase>
<ButtonBase <ButtonBase
sx={{ sx={{
"&:hover": { backgroundColor: "secondary.main" }, '&:hover': { backgroundColor: theme.palette.background.paper },
transition: "all 0.1s ease-in-out", transition: 'all 0.1s ease-in-out',
padding: "5px", padding: '5px',
borderRadius: "5px", borderRadius: '5px',
gap: "5px", gap: '5px',
}} }}
onClick={async () => { onClick={async () => {
executeEvent("openWalletsApp", { executeEvent('openWalletsApp', {});
}}
});
}}
> >
<AccountBalanceWalletIcon <AccountBalanceWalletIcon
sx={{ sx={{
color: "white", color: theme.palette.text.primary,
}} }}
/> />
<Typography <Typography
sx={{ sx={{
fontSize: "1rem", fontSize: '1rem',
}} }}
> >
Wallets {t('core:wallet', { count: 100, postProcess: 'capitalize' })}
</Typography> </Typography>
</ButtonBase> </ButtonBase>
</Box> </Box>

View File

@ -1,16 +1,16 @@
import { Box, Button, Divider, Typography } from "@mui/material"; import { Box, Divider, Typography, useTheme } from '@mui/material';
import React from "react"; import React from 'react';
import { Spacer } from "../../common/Spacer"; import { Spacer } from '../../common/Spacer';
import { ListOfThreadPostsWatched } from "./ListOfThreadPostsWatched"; import { ThingsToDoInitial } from './ThingsToDoInitial';
import { ThingsToDoInitial } from "./ThingsToDoInitial"; import { GroupJoinRequests } from './GroupJoinRequests';
import { GroupJoinRequests } from "./GroupJoinRequests"; import { GroupInvites } from './GroupInvites';
import { GroupInvites } from "./GroupInvites"; import { ListOfGroupPromotions } from './ListOfGroupPromotions';
import RefreshIcon from "@mui/icons-material/Refresh"; import { QortPrice } from '../Home/QortPrice';
import { ListOfGroupPromotions } from "./ListOfGroupPromotions"; import ExploreIcon from '@mui/icons-material/Explore';
import { QortPrice } from "../Home/QortPrice"; import { Explore } from '../Explore/Explore';
import ExploreIcon from "@mui/icons-material/Explore"; import { NewUsersCTA } from '../Home/NewUsersCTA';
import { Explore } from "../Explore/Explore"; import { useTranslation } from 'react-i18next';
import { NewUsersCTA } from "../Home/NewUsersCTA";
export const HomeDesktop = ({ export const HomeDesktop = ({
refreshHomeDataFunc, refreshHomeDataFunc,
myAddress, myAddress,
@ -30,93 +30,97 @@ export const HomeDesktop = ({
}) => { }) => {
const [checked1, setChecked1] = React.useState(false); const [checked1, setChecked1] = React.useState(false);
const [checked2, setChecked2] = React.useState(false); const [checked2, setChecked2] = React.useState(false);
React.useEffect(() => {
if (balance && +balance >= 6) {
setChecked1(true);
}
}, [balance]);
React.useEffect(() => {
if (name) setChecked2(true);
}, [name]);
const isLoaded = React.useMemo(()=> {
if(userInfo !== null) return true
return false
}, [ userInfo])
const hasDoneNameAndBalanceAndIsLoaded = React.useMemo(()=> {
if(isLoaded && checked1 && checked2) return true
return false
}, [checked1, isLoaded, checked2])
const { t } = useTranslation(['core']);
const theme = useTheme();
React.useEffect(() => {
if (balance && +balance >= 6) {
setChecked1(true);
}
}, [balance]);
React.useEffect(() => {
if (name) setChecked2(true);
}, [name]);
const isLoaded = React.useMemo(() => {
if (userInfo !== null) return true;
return false;
}, [userInfo]);
const hasDoneNameAndBalanceAndIsLoaded = React.useMemo(() => {
if (isLoaded && checked1 && checked2) return true;
return false;
}, [checked1, isLoaded, checked2]);
return ( return (
<Box <Box
sx={{ sx={{
display: desktopViewMode === "home" ? "flex" : "none", alignItems: 'center',
width: "100%", display: desktopViewMode === 'home' ? 'flex' : 'none',
flexDirection: "column", flexDirection: 'column',
height: "100%", height: '100%',
overflow: "auto", overflow: 'auto',
alignItems: "center", width: '100%',
}} }}
> >
<Spacer height="20px" /> <Spacer height="20px" />
<Box <Box
sx={{ sx={{
display: "flex", alignItems: 'flex-start',
width: "100%", display: 'flex',
flexDirection: "column", flexDirection: 'column',
height: "100%", height: '100%',
alignItems: "flex-start", maxWidth: '1036px',
maxWidth: "1036px", width: '100%',
}} }}
> >
<Typography <Typography
sx={{ sx={{
color: "rgba(255, 255, 255, 1)", color: theme.palette.text.primary,
fontWeight: 400, fontWeight: 400,
fontSize: userInfo?.name?.length > 15 ? "16px" : "20px", fontSize: userInfo?.name?.length > 15 ? '16px' : '20px',
padding: "10px", padding: '10px',
}} }}
> >
Welcome {t('core:welcome', { postProcess: 'capitalize' })}
{userInfo?.name ? ( {userInfo?.name ? (
<span <span
style={{ style={{
fontStyle: "italic", fontStyle: 'italic',
}} }}
>{`, ${userInfo?.name}`}</span> >{`, ${userInfo?.name}`}</span>
) : null} ) : null}
</Typography> </Typography>
<Spacer height="30px" /> <Spacer height="30px" />
{!isLoadingGroups && ( {!isLoadingGroups && (
<Box <Box
sx={{ sx={{
display: "flex", display: 'flex',
gap: "20px", flexWrap: 'wrap',
flexWrap: "wrap", gap: '20px',
width: "100%", justifyContent: 'center',
justifyContent: "center", width: '100%',
}} }}
> >
<Box <Box
sx={{ sx={{
display: "flex", display: 'flex',
gap: "20px", flexDirection: 'column',
flexWrap: "wrap", flexWrap: 'wrap',
flexDirection: "column", gap: '20px',
}} }}
> >
<Box <Box
sx={{ sx={{
width: "330px", alignItems: 'center',
display: "flex", display: 'flex',
alignItems: "center", justifyContent: 'center',
justifyContent: "center", width: '330px',
}} }}
> >
<ThingsToDoInitial <ThingsToDoInitial
@ -125,12 +129,12 @@ export const HomeDesktop = ({
name={userInfo?.name} name={userInfo?.name}
userInfo={userInfo} userInfo={userInfo}
hasGroups={ hasGroups={
groups?.filter((item) => item?.groupId !== "0").length !== 0 groups?.filter((item) => item?.groupId !== '0').length !== 0
} }
/> />
</Box> </Box>
{desktopViewMode === "home" && ( {desktopViewMode === 'home' && (
<> <>
{/* <Box sx={{ {/* <Box sx={{
width: '330px', width: '330px',
@ -140,105 +144,101 @@ export const HomeDesktop = ({
}}> }}>
<ListOfThreadPostsWatched /> <ListOfThreadPostsWatched />
</Box> */} </Box> */}
{hasDoneNameAndBalanceAndIsLoaded && ( {hasDoneNameAndBalanceAndIsLoaded && (
<> <>
<Box <Box
sx={{ sx={{
width: "330px", alignItems: 'center',
display: "flex", display: 'flex',
alignItems: "center", justifyContent: 'center',
justifyContent: "center", width: '330px',
}} }}
> >
<GroupJoinRequests <GroupJoinRequests
setGroupSection={setGroupSection} setGroupSection={setGroupSection}
setSelectedGroup={setSelectedGroup} setSelectedGroup={setSelectedGroup}
getTimestampEnterChat={getTimestampEnterChat} getTimestampEnterChat={getTimestampEnterChat}
setOpenManageMembers={setOpenManageMembers} setOpenManageMembers={setOpenManageMembers}
myAddress={myAddress} myAddress={myAddress}
groups={groups} groups={groups}
setMobileViewMode={setMobileViewMode} setMobileViewMode={setMobileViewMode}
setDesktopViewMode={setDesktopViewMode} setDesktopViewMode={setDesktopViewMode}
/> />
</Box> </Box>
<Box
sx={{ <Box
width: "330px", sx={{
display: "flex", alignItems: 'center',
alignItems: "center", display: 'flex',
justifyContent: "center", justifyContent: 'center',
}} width: '330px',
> }}
<GroupInvites >
setOpenAddGroup={setOpenAddGroup} <GroupInvites
myAddress={myAddress} setOpenAddGroup={setOpenAddGroup}
groups={groups} myAddress={myAddress}
setMobileViewMode={setMobileViewMode} groups={groups}
/> setMobileViewMode={setMobileViewMode}
</Box> />
</> </Box>
)} </>
)}
</> </>
)} )}
</Box> </Box>
<QortPrice /> <QortPrice />
</Box> </Box>
)} )}
{!isLoadingGroups && ( {!isLoadingGroups && (
<> <>
<Spacer height="60px" /> <Spacer height="60px" />
<Divider
color="secondary" <Divider
sx={{ color="secondary"
width: "100%",
}}
>
<Box
sx={{
display: "flex",
gap: "10px",
alignItems: "center",
}}
>
<ExploreIcon
sx={{ sx={{
color: "white", width: '100%',
}}
/>{" "}
<Typography
sx={{
fontSize: "1rem",
}} }}
> >
Explore <Box
</Typography>{" "} sx={{
</Box> alignItems: 'center',
</Divider> display: 'flex',
{!hasDoneNameAndBalanceAndIsLoaded && ( gap: '10px',
<Spacer height="40px" /> }}
)} >
<Box <ExploreIcon
sx={{ sx={{
display: "flex", ccolor: theme.palette.text.primary,
gap: "20px", }}
flexWrap: "wrap", />{' '}
width: "100%", <Typography
justifyContent: "center", sx={{
}} fontSize: '1rem',
> }}
{hasDoneNameAndBalanceAndIsLoaded && ( >
<ListOfGroupPromotions /> {t('tutorial:initial.explore', { postProcess: 'capitalize' })}
</Typography>{' '}
</Box>
</Divider>
)} {!hasDoneNameAndBalanceAndIsLoaded && <Spacer height="40px" />}
<Box
<Explore setDesktopViewMode={setDesktopViewMode} /> sx={{
</Box> display: 'flex',
flexWrap: 'wrap',
<NewUsersCTA balance={balance} /> gap: '20px',
justifyContent: 'center',
width: '100%',
}}
>
{hasDoneNameAndBalanceAndIsLoaded && <ListOfGroupPromotions />}
<Explore setDesktopViewMode={setDesktopViewMode} />
</Box>
<NewUsersCTA balance={balance} />
</> </>
)} )}
</Box> </Box>
<Spacer height="26px" /> <Spacer height="26px" />

View File

@ -1,8 +1,9 @@
import React, { useCallback, useEffect, useState } from "react"; import { useCallback, useEffect, useState } from 'react';
import { getBaseApiReact } from "../../App"; import { getBaseApiReact } from '../../App';
import { Box, Tooltip, Typography } from "@mui/material"; import { Box, Tooltip, Typography, useTheme } from '@mui/material';
import { BarSpinner } from "../../common/Spinners/BarSpinner/BarSpinner"; import { BarSpinner } from '../../common/Spinners/BarSpinner/BarSpinner';
import { formatDate } from "../../utils/time"; import { formatDate } from '../../utils/time';
import { useTranslation } from 'react-i18next';
function getAverageLtcPerQort(trades) { function getAverageLtcPerQort(trades) {
let totalQort = 0; let totalQort = 0;
@ -38,6 +39,8 @@ export const QortPrice = () => {
const [supply, setSupply] = useState(null); const [supply, setSupply] = useState(null);
const [lastBlock, setLastBlock] = useState(null); const [lastBlock, setLastBlock] = useState(null);
const [loading, setLoading] = useState(true); const [loading, setLoading] = useState(true);
const { t } = useTranslation(['core', 'tutorial']);
const theme = useTheme();
const getPrice = useCallback(async () => { const getPrice = useCallback(async () => {
try { try {
@ -101,64 +104,63 @@ export const QortPrice = () => {
return () => clearInterval(interval); return () => clearInterval(interval);
}, [getPrice]); }, [getPrice]);
return ( return (
<Box <Box
sx={{ sx={{
display: "flex", display: 'flex',
gap: "20px", gap: '20px',
flexWrap: "wrap", flexWrap: 'wrap',
flexDirection: "column", flexDirection: 'column',
width: "322px", width: '322px',
}} }}
> >
<Tooltip <Tooltip
title={ title={
<span style={{ color: "white", fontSize: "14px", fontWeight: 700 }}> <span style={{ color: 'white', fontSize: '14px', fontWeight: 700 }}>
Based on the latest 20 trades Based on the latest 20 trades
</span> </span>
} }
placement="bottom" placement="bottom"
arrow arrow
sx={{ fontSize: "24" }} sx={{ fontSize: '24' }}
slotProps={{ slotProps={{
tooltip: { tooltip: {
sx: { sx: {
color: "#ffffff", color: theme.palette.text.primary,
backgroundColor: "#444444", backgroundColor: theme.palette.background.default,
}, },
}, },
arrow: { arrow: {
sx: { sx: {
color: "#444444", color: theme.palette.text.primary,
}, },
}, },
}} }}
> >
<Box <Box
sx={{ sx={{
width: "322px", display: 'flex',
display: "flex", flexDirection: 'row',
flexDirection: "row", gap: '10px',
gap: "10px", justifyContent: 'space-between',
width: '322px',
justifyContent: "space-between",
}} }}
> >
<Typography <Typography
sx={{ sx={{
fontSize: "1rem", fontSize: '1rem',
fontWeight: "bold", fontWeight: 'bold',
}} }}
> >
Price {t('core:price', { postProcess: 'capitalize' })}
</Typography> </Typography>
{!ltcPerQort ? ( {!ltcPerQort ? (
<BarSpinner width="16px" color="white" /> <BarSpinner width="16px" color="white" />
) : ( ) : (
<Typography <Typography
sx={{ sx={{
fontSize: "1rem", fontSize: '1rem',
}} }}
> >
{ltcPerQort} LTC/QORT {ltcPerQort} LTC/QORT
@ -168,28 +170,28 @@ export const QortPrice = () => {
</Tooltip> </Tooltip>
<Box <Box
sx={{ sx={{
width: "322px", display: 'flex',
display: "flex", flexDirection: 'row',
flexDirection: "row", gap: '10px',
gap: "10px", justifyContent: 'space-between',
width: '322px',
justifyContent: "space-between",
}} }}
> >
<Typography <Typography
sx={{ sx={{
fontSize: "1rem", fontSize: '1rem',
fontWeight: "bold", fontWeight: 'bold',
}} }}
> >
Supply {t('core:supply', { postProcess: 'capitalize' })}
</Typography> </Typography>
{!supply ? ( {!supply ? (
<BarSpinner width="16px" color="white" /> <BarSpinner width="16px" color="white" />
) : ( ) : (
<Typography <Typography
sx={{ sx={{
fontSize: "1rem", fontSize: '1rem',
}} }}
> >
{supply} QORT {supply} QORT
@ -197,60 +199,58 @@ export const QortPrice = () => {
)} )}
</Box> </Box>
<Tooltip <Tooltip
title={ title={
<span style={{ color: "white", fontSize: "14px", fontWeight: 700 }}> <span style={{ color: 'white', fontSize: '14px', fontWeight: 700 }}>
{lastBlock?.timestamp && formatDate(lastBlock?.timestamp)} {lastBlock?.timestamp && formatDate(lastBlock?.timestamp)}
</span> </span>
} }
placement="bottom" placement="bottom"
arrow arrow
sx={{ fontSize: "24" }} sx={{ fontSize: '24' }}
slotProps={{ slotProps={{
tooltip: { tooltip: {
sx: { sx: {
color: "#ffffff", color: theme.palette.text.primary,
backgroundColor: "#444444", backgroundColor: theme.palette.background.default,
},
}, },
arrow: { },
sx: { arrow: {
color: "#444444", sx: {
}, color: theme.palette.text.primary,
}, },
}} },
>
<Box
sx={{
width: "322px",
display: "flex",
flexDirection: "row",
gap: "10px",
justifyContent: "space-between",
}} }}
> >
<Box
sx={{
display: 'flex',
flexDirection: 'row',
gap: '10px',
justifyContent: 'space-between',
width: '322px',
}}
>
<Typography <Typography
sx={{ sx={{
fontSize: "1rem", fontSize: '1rem',
fontWeight: "bold", fontWeight: 'bold',
}} }}
> >
Last height {t('core:last_height', { postProcess: 'capitalize' })}
</Typography> </Typography>
{!lastBlock?.height ? ( {!lastBlock?.height ? (
<BarSpinner width="16px" color="white" /> <BarSpinner width="16px" color="white" />
) : ( ) : (
<Typography <Typography
sx={{ sx={{
fontSize: "1rem", fontSize: '1rem',
}} }}
> >
{lastBlock?.height} {lastBlock?.height}
</Typography> </Typography>
)} )}
</Box>
</Box>
</Tooltip> </Tooltip>
</Box> </Box>
); );