diff --git a/electron/store.js b/electron/store.js index 5577decff..afbc7f62d 100644 --- a/electron/store.js +++ b/electron/store.js @@ -4,6 +4,7 @@ const defaultSchema = { isInitialFunded: { type: 'boolean', default: false }, firstStakingRewardAchieved: { type: 'boolean', default: false }, firstRewardNotificationShown: { type: 'boolean', default: false }, + agentEvictionAlertShown: { type: 'boolean', default: false }, }; const setupStoreIpc = async (ipcChannel, mainWindow, storeInitialValues) => { diff --git a/frontend/components/Main/MainOlasBalance.tsx b/frontend/components/Main/MainOlasBalance.tsx index f51cf2ef9..38e358350 100644 --- a/frontend/components/Main/MainOlasBalance.tsx +++ b/frontend/components/Main/MainOlasBalance.tsx @@ -1,17 +1,20 @@ import { InfoCircleOutlined } from '@ant-design/icons'; -import { Flex, Skeleton, Tooltip, Typography } from 'antd'; +import { Button, Flex, Skeleton, Tooltip, Typography } from 'antd'; import { useMemo } from 'react'; import styled from 'styled-components'; +import { Alert } from '@/components/Alert'; import { COLOR } from '@/constants/colors'; import { UNICODE_SYMBOLS } from '@/constants/symbols'; import { useBalance } from '@/hooks/useBalance'; +import { useElectronApi } from '@/hooks/useElectronApi'; import { useReward } from '@/hooks/useReward'; +import { useStore } from '@/hooks/useStore'; import { balanceFormat } from '@/utils/numberFormatters'; import { CardSection } from '../styled/CardSection'; -const { Text } = Typography; +const { Text, Title } = Typography; const Balance = styled.span` letter-spacing: -2px; margin-right: 4px; @@ -103,9 +106,70 @@ const CurrentBalance = () => { ); }; +const AvoidSuspensionAlertContainer = styled.div` + .ant-alert-info { + margin-bottom: 8px; + .anticon.ant-alert-icon { + height: 20px; + width: 20px; + svg { + width: 100%; + height: 100%; + } + } + } +`; + +const AvoidSuspensionAlert = () => { + const { store } = useElectronApi(); + + return ( + + + + Avoid suspension! + + + Run your agent for at least half an hour a day to make sure it + hits its targets. If it misses its targets 2 days in a row, it’ll + be suspended. You won’t be able to run it or earn rewards for + several days. + + + + } + /> + + ); +}; + export const MainOlasBalance = () => { + const { storeState } = useStore(); const { isBalanceLoaded, totalOlasBalance } = useBalance(); + // If first reward notification is shown BUT + // agent eviction alert is NOT yet shown, show this alert. + const canShowAvoidSuspensionAlert = useMemo(() => { + if (!storeState) return false; + + return ( + storeState.firstRewardNotificationShown && + !storeState.agentEvictionAlertShown + ); + }, [storeState]); + const balance = useMemo(() => { if (totalOlasBalance === undefined) return '--'; return balanceFormat(totalOlasBalance, 2); @@ -113,6 +177,7 @@ export const MainOlasBalance = () => { return ( + {canShowAvoidSuspensionAlert ? : null} {isBalanceLoaded ? ( <> diff --git a/frontend/components/Main/MainRewards.tsx b/frontend/components/Main/MainRewards.tsx index 8f775b163..50ef32f30 100644 --- a/frontend/components/Main/MainRewards.tsx +++ b/frontend/components/Main/MainRewards.tsx @@ -65,7 +65,7 @@ const DisplayRewards = () => { const SHARE_TEXT = `I just earned my first reward through the Operate app powered by #olas!\n\nDownload the Pearl app:`; const OPERATE_URL = 'https://olas.network/operate?pearl=first-reward'; -const NotifyRewards = () => { +const NotifyRewardsModal = () => { const { isEligibleForRewards, availableRewardsForEpochEth } = useReward(); const { totalOlasBalance } = useBalance(); const { showNotification, store } = useElectronApi(); @@ -179,6 +179,6 @@ const NotifyRewards = () => { export const MainRewards = () => ( <> - + ); diff --git a/frontend/types/ElectronApi.ts b/frontend/types/ElectronApi.ts index 2f586a0d9..df0456a47 100644 --- a/frontend/types/ElectronApi.ts +++ b/frontend/types/ElectronApi.ts @@ -3,6 +3,7 @@ export type ElectronStore = { isInitialFunded?: boolean; firstStakingRewardAchieved?: boolean; firstRewardNotificationShown?: boolean; + agentEvictionAlertShown?: boolean; }; export type ElectronTrayIconStatus = 'low-gas' | 'running' | 'paused';