summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorOliver <oliver@mohlin.dev>2025-02-07 09:36:18 +0100
committerOliver Mohlin <oliver@mohlin.dev>2025-02-25 09:36:34 +0100
commitd59d7e25e639b1bc69c9be6548ce01b3e9ee0fc0 (patch)
treef037c90f6c6b5426831311440c75d98732fb7fe0
parent7673f87e3d33c5b2221ba7acc0f767f9a1db4412 (diff)
downloadmullvadvpn-d59d7e25e639b1bc69c9be6548ce01b3e9ee0fc0.tar.xz
mullvadvpn-d59d7e25e639b1bc69c9be6548ce01b3e9ee0fc0.zip
Add IconBadge component
-rw-r--r--desktop/packages/mullvad-vpn/src/renderer/components/DeviceRevokedView.tsx18
-rw-r--r--desktop/packages/mullvad-vpn/src/renderer/components/ExpiredAccountAddTime.tsx11
-rw-r--r--desktop/packages/mullvad-vpn/src/renderer/components/ExpiredAccountErrorView.tsx10
-rw-r--r--desktop/packages/mullvad-vpn/src/renderer/components/ExpiredAccountErrorViewStyles.tsx7
-rw-r--r--desktop/packages/mullvad-vpn/src/renderer/components/Login.tsx17
-rw-r--r--desktop/packages/mullvad-vpn/src/renderer/components/Modal.tsx7
-rw-r--r--desktop/packages/mullvad-vpn/src/renderer/components/ProblemReport.tsx20
-rw-r--r--desktop/packages/mullvad-vpn/src/renderer/components/RedeemVoucher.tsx12
-rw-r--r--desktop/packages/mullvad-vpn/src/renderer/components/RedeemVoucherStyles.tsx8
-rw-r--r--desktop/packages/mullvad-vpn/src/renderer/components/TooManyDevices.tsx16
-rw-r--r--desktop/packages/mullvad-vpn/src/renderer/lib/icon-badge/IconBadge.tsx14
-rw-r--r--desktop/packages/mullvad-vpn/src/renderer/lib/icon-badge/index.ts1
12 files changed, 69 insertions, 72 deletions
diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/DeviceRevokedView.tsx b/desktop/packages/mullvad-vpn/src/renderer/components/DeviceRevokedView.tsx
index ec4d1e38ba..3125c1c3e1 100644
--- a/desktop/packages/mullvad-vpn/src/renderer/components/DeviceRevokedView.tsx
+++ b/desktop/packages/mullvad-vpn/src/renderer/components/DeviceRevokedView.tsx
@@ -2,8 +2,9 @@ import styled from 'styled-components';
import { messages } from '../../shared/gettext';
import { useAppContext } from '../context';
-import { Image } from '../lib/components';
-import { Colors } from '../lib/foundations';
+import { Flex } from '../lib/components';
+import { Colors, Spacings } from '../lib/foundations';
+import { IconBadge } from '../lib/icon-badge';
import { useSelector } from '../redux/store';
import { AppMainHeader } from './app-main-header';
import * as AppButton from './AppButton';
@@ -28,13 +29,6 @@ export const StyledBody = styled.div({
padding: `0 ${measurements.horizontalViewMargin}`,
});
-export const StyledStatusIcon = styled.div({
- alignSelf: 'center',
- width: '60px',
- height: '60px',
- marginBottom: '18px',
-});
-
export const StyledTitle = styled.span(bigText, {
lineHeight: '38px',
marginBottom: '8px',
@@ -61,9 +55,9 @@ export function DeviceRevokedView() {
<StyledCustomScrollbars fillContainer>
<StyledContainer>
<StyledBody>
- <StyledStatusIcon>
- <Image source="icon-fail" height={60} width={60} />
- </StyledStatusIcon>
+ <Flex $justifyContent="center" $margin={{ bottom: Spacings.spacing5 }}>
+ <IconBadge state="negative" />
+ </Flex>
<StyledTitle data-testid="title">
{messages.pgettext('device-management', 'Device is inactive')}
</StyledTitle>
diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/ExpiredAccountAddTime.tsx b/desktop/packages/mullvad-vpn/src/renderer/components/ExpiredAccountAddTime.tsx
index b0d1cc1f6a..8a72a30cfa 100644
--- a/desktop/packages/mullvad-vpn/src/renderer/components/ExpiredAccountAddTime.tsx
+++ b/desktop/packages/mullvad-vpn/src/renderer/components/ExpiredAccountAddTime.tsx
@@ -9,9 +9,10 @@ import { formatRelativeDate } from '../../shared/date-helper';
import { messages } from '../../shared/gettext';
import { useAppContext } from '../context';
import useActions from '../lib/actionsHook';
-import { Icon, Image } from '../lib/components';
-import { Colors } from '../lib/foundations';
+import { Flex, Icon } from '../lib/components';
+import { Colors, Spacings } from '../lib/foundations';
import { transitions, useHistory } from '../lib/history';
+import { IconBadge } from '../lib/icon-badge';
import { generateRoutePath } from '../lib/routeHelpers';
import { RoutePath } from '../lib/routes';
import account from '../redux/account/actions';
@@ -165,9 +166,9 @@ export function TimeAdded(props: ITimeAddedProps) {
<StyledCustomScrollbars fillContainer>
<StyledContainer>
<StyledBody>
- <StyledStatusIcon>
- <Image source="icon-success" height={60} width={60} />
- </StyledStatusIcon>
+ <Flex $justifyContent="center" $margin={{ bottom: Spacings.spacing5 }}>
+ <IconBadge state="positive" />
+ </Flex>
<StyledTitle>
{props.title ?? messages.pgettext('connect-view', 'Time was successfully added')}
</StyledTitle>
diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/ExpiredAccountErrorView.tsx b/desktop/packages/mullvad-vpn/src/renderer/components/ExpiredAccountErrorView.tsx
index 677af5a60a..785d6405e1 100644
--- a/desktop/packages/mullvad-vpn/src/renderer/components/ExpiredAccountErrorView.tsx
+++ b/desktop/packages/mullvad-vpn/src/renderer/components/ExpiredAccountErrorView.tsx
@@ -6,9 +6,10 @@ import { messages } from '../../shared/gettext';
import log from '../../shared/logging';
import { capitalizeEveryWord } from '../../shared/string-helpers';
import { useAppContext } from '../context';
-import { Flex, Icon, Image } from '../lib/components';
+import { Flex, Icon } from '../lib/components';
import { Spacings } from '../lib/foundations';
import { useHistory } from '../lib/history';
+import { IconBadge } from '../lib/icon-badge';
import { RoutePath } from '../lib/routes';
import { useSelector } from '../redux/store';
import { AppMainHeader } from './app-main-header';
@@ -26,7 +27,6 @@ import {
StyledDeviceLabel,
StyledMessage,
StyledModalCellContainer,
- StyledStatusIcon,
StyledTitle,
} from './ExpiredAccountErrorViewStyles';
import { Footer, Layout } from './Layout';
@@ -156,9 +156,9 @@ function Content() {
return (
<>
- <StyledStatusIcon>
- <Image source="icon-fail" height={60} width={60} />
- </StyledStatusIcon>
+ <Flex $justifyContent="center" $margin={{ bottom: Spacings.spacing5 }}>
+ <IconBadge state="negative" />
+ </Flex>
<StyledTitle data-testid="title">
{messages.pgettext('connect-view', 'Out of time')}
</StyledTitle>
diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/ExpiredAccountErrorViewStyles.tsx b/desktop/packages/mullvad-vpn/src/renderer/components/ExpiredAccountErrorViewStyles.tsx
index ba4c283510..81ba2496a8 100644
--- a/desktop/packages/mullvad-vpn/src/renderer/components/ExpiredAccountErrorViewStyles.tsx
+++ b/desktop/packages/mullvad-vpn/src/renderer/components/ExpiredAccountErrorViewStyles.tsx
@@ -52,13 +52,6 @@ export const StyledAccountNumberMessage = styled.span(tinyText, {
color: Colors.white,
});
-export const StyledStatusIcon = styled.div({
- alignSelf: 'center',
- width: '60px',
- height: '60px',
- marginBottom: '18px',
-});
-
export const StyledAccountNumberContainer = styled.div({
display: 'flex',
height: '50px',
diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/Login.tsx b/desktop/packages/mullvad-vpn/src/renderer/components/Login.tsx
index 063427d241..bbd4a32584 100644
--- a/desktop/packages/mullvad-vpn/src/renderer/components/Login.tsx
+++ b/desktop/packages/mullvad-vpn/src/renderer/components/Login.tsx
@@ -8,19 +8,10 @@ import { messages } from '../../shared/gettext';
import { useAppContext } from '../context';
import { formatAccountNumber } from '../lib/account';
import useActions from '../lib/actionsHook';
-import {
- Box,
- Button,
- Flex,
- Icon,
- Image,
- Label,
- LabelTiny,
- Spinner,
- TitleMedium,
-} from '../lib/components';
+import { Box, Button, Flex, Icon, Label, LabelTiny, Spinner, TitleMedium } from '../lib/components';
import { Colors, Spacings } from '../lib/foundations';
import { formatHtml } from '../lib/html-formatter';
+import { IconBadge } from '../lib/icon-badge';
import accountActions from '../redux/account/actions';
import { LoginState } from '../redux/account/reducers';
import { useSelector } from '../redux/store';
@@ -262,9 +253,9 @@ class Login extends React.Component<IProps, IState> {
case 'logging in':
return <Spinner size="big" />;
case 'failed':
- return <Image source="icon-fail" height={48} width={48} />;
+ return <IconBadge state="negative" />;
case 'ok':
- return <Image source="icon-success" height={48} width={48} />;
+ return <IconBadge state="positive" />;
default:
return null;
}
diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/Modal.tsx b/desktop/packages/mullvad-vpn/src/renderer/components/Modal.tsx
index f9e9dc2f44..3409ddac14 100644
--- a/desktop/packages/mullvad-vpn/src/renderer/components/Modal.tsx
+++ b/desktop/packages/mullvad-vpn/src/renderer/components/Modal.tsx
@@ -3,8 +3,9 @@ import ReactDOM from 'react-dom';
import styled from 'styled-components';
import log from '../../shared/logging';
-import { Icon, IconProps, Image, Spinner } from '../lib/components';
+import { Icon, IconProps, Spinner } from '../lib/components';
import { Colors } from '../lib/foundations';
+import { IconBadge } from '../lib/icon-badge';
import { useEffectEvent } from '../lib/utility-hooks';
import { useWillExit } from '../lib/will-exit';
import * as AppButton from './AppButton';
@@ -333,9 +334,9 @@ class ModalAlertImpl extends React.Component<IModalAlertImplProps, IModalAlertSt
case ModalAlertType.loading:
return <Spinner size="big" />;
case ModalAlertType.success:
- return <Image source="icon-success" height={48} width={48} />;
+ return <IconBadge state="positive" />;
case ModalAlertType.failure:
- return <Image source="icon-fail" height={48} width={48} />;
+ return <IconBadge state="negative" />;
}
return <Icon size="big" icon={source} color={color} />;
diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/ProblemReport.tsx b/desktop/packages/mullvad-vpn/src/renderer/components/ProblemReport.tsx
index a0c29e832a..86064e1fd7 100644
--- a/desktop/packages/mullvad-vpn/src/renderer/components/ProblemReport.tsx
+++ b/desktop/packages/mullvad-vpn/src/renderer/components/ProblemReport.tsx
@@ -16,8 +16,10 @@ import { messages } from '../../shared/gettext';
import { getDownloadUrl } from '../../shared/version';
import { useAppContext } from '../context';
import useActions from '../lib/actionsHook';
-import { Icon, Image, Spinner } from '../lib/components';
+import { Flex, Icon, Spinner } from '../lib/components';
+import { Spacings } from '../lib/foundations';
import { useHistory } from '../lib/history';
+import { IconBadge } from '../lib/icon-badge';
import { useEffectEvent } from '../lib/utility-hooks';
import { useSelector } from '../redux/store';
import support from '../redux/support/actions';
@@ -232,9 +234,11 @@ function Sent() {
return (
<StyledContent>
<StyledForm>
- <StyledStatusIcon>
- <Image source="icon-success" height={60} width={60} />
- </StyledStatusIcon>
+ <Flex
+ $justifyContent="center"
+ $margin={{ top: Spacings.spacing6, bottom: Spacings.spacing5 }}>
+ <IconBadge state="positive" />
+ </Flex>
<StyledSendStatus>{messages.pgettext('support-view', 'Sent')}</StyledSendStatus>
<StyledSentMessage>
@@ -257,9 +261,11 @@ function Failed() {
return (
<StyledContent>
<StyledForm>
- <StyledStatusIcon>
- <Image source="icon-fail" height={60} width={60} />
- </StyledStatusIcon>
+ <Flex
+ $justifyContent="center"
+ $margin={{ top: Spacings.spacing6, bottom: Spacings.spacing5 }}>
+ <IconBadge state="negative" />
+ </Flex>
<StyledSendStatus>{messages.pgettext('support-view', 'Failed to send')}</StyledSendStatus>
<StyledSentMessage>
{messages.pgettext(
diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/RedeemVoucher.tsx b/desktop/packages/mullvad-vpn/src/renderer/components/RedeemVoucher.tsx
index 9e7390c276..d39f6ce1d3 100644
--- a/desktop/packages/mullvad-vpn/src/renderer/components/RedeemVoucher.tsx
+++ b/desktop/packages/mullvad-vpn/src/renderer/components/RedeemVoucher.tsx
@@ -6,8 +6,9 @@ import { VoucherResponse } from '../../shared/daemon-rpc-types';
import { formatRelativeDate } from '../../shared/date-helper';
import { messages } from '../../shared/gettext';
import { useAppContext } from '../context';
-import { Flex, Image, Spinner } from '../lib/components';
+import { Flex, Spinner } from '../lib/components';
import { Spacings } from '../lib/foundations';
+import { IconBadge } from '../lib/icon-badge';
import { useSelector } from '../redux/store';
import * as AppButton from './AppButton';
import { ModalAlert } from './Modal';
@@ -17,7 +18,6 @@ import {
StyledInput,
StyledLabel,
StyledProgressResponse,
- StyledStatusIcon,
StyledTitle,
} from './RedeemVoucherStyles';
@@ -226,9 +226,11 @@ export function RedeemVoucherAlert(props: IRedeemVoucherAlertProps) {
</AppButton.BlueButton>,
]}
close={props.onClose}>
- <StyledStatusIcon>
- <Image source="icon-success" height={60} width={60} />
- </StyledStatusIcon>
+ <Flex
+ $justifyContent="center"
+ $margin={{ top: Spacings.spacing6, bottom: Spacings.spacing5 }}>
+ <IconBadge state="positive" />
+ </Flex>
<StyledTitle>
{messages.pgettext('redeem-voucher-view', 'Voucher was successfully redeemed.')}
</StyledTitle>
diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/RedeemVoucherStyles.tsx b/desktop/packages/mullvad-vpn/src/renderer/components/RedeemVoucherStyles.tsx
index ce9c5e9f9e..6dc538c3b3 100644
--- a/desktop/packages/mullvad-vpn/src/renderer/components/RedeemVoucherStyles.tsx
+++ b/desktop/packages/mullvad-vpn/src/renderer/components/RedeemVoucherStyles.tsx
@@ -43,14 +43,6 @@ export const StyledEmptyResponse = styled.span({
marginTop: '8px',
});
-export const StyledStatusIcon = styled.div({
- alignSelf: 'center',
- width: '60px',
- height: '60px',
- marginBottom: '18px',
- marginTop: '25px',
-});
-
export const StyledTitle = styled.span(smallText, {
lineHeight: '22px',
fontWeight: 400,
diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/TooManyDevices.tsx b/desktop/packages/mullvad-vpn/src/renderer/components/TooManyDevices.tsx
index a020980def..ce1f4f3fd1 100644
--- a/desktop/packages/mullvad-vpn/src/renderer/components/TooManyDevices.tsx
+++ b/desktop/packages/mullvad-vpn/src/renderer/components/TooManyDevices.tsx
@@ -7,10 +7,11 @@ import { messages } from '../../shared/gettext';
import log from '../../shared/logging';
import { capitalizeEveryWord } from '../../shared/string-helpers';
import { useAppContext } from '../context';
-import { Button, Flex, IconButton, Image, ImageProps, Spinner } from '../lib/components';
+import { Button, Flex, IconButton, Spinner } from '../lib/components';
import { Colors, Spacings } from '../lib/foundations';
import { transitions, useHistory } from '../lib/history';
import { formatHtml } from '../lib/html-formatter';
+import { IconBadge, IconBadgeProps } from '../lib/icon-badge';
import { RoutePath } from '../lib/routes';
import { useBoolean } from '../lib/utility-hooks';
import { useSelector } from '../redux/store';
@@ -28,7 +29,6 @@ const StyledCustomScrollbars = styled(CustomScrollbars)({
});
const StyledContainer = styled(SettingsContainer)({
- paddingTop: '14px',
minHeight: '100%',
});
@@ -115,8 +115,10 @@ export default function TooManyDevices() {
<StyledCustomScrollbars fillContainer>
<StyledContainer>
<StyledBody>
- <Flex $justifyContent="center" $margin={{ vertical: Spacings.spacing3 }}>
- <Image key={imageSource} source={imageSource} height={60} width={60} />
+ <Flex
+ $justifyContent="center"
+ $margin={{ top: Spacings.spacing6, bottom: Spacings.spacing5 }}>
+ <IconBadge key={imageSource} state={imageSource} />
</Flex>
{devices !== undefined && (
<>
@@ -297,11 +299,11 @@ function Device(props: IDeviceProps) {
);
}
-function getIconSource(devices: Array<IDevice>): ImageProps['source'] {
+function getIconSource(devices: Array<IDevice>): IconBadgeProps['state'] {
if (devices.length === 5) {
- return 'icon-fail';
+ return 'negative';
} else {
- return 'icon-success';
+ return 'positive';
}
}
diff --git a/desktop/packages/mullvad-vpn/src/renderer/lib/icon-badge/IconBadge.tsx b/desktop/packages/mullvad-vpn/src/renderer/lib/icon-badge/IconBadge.tsx
new file mode 100644
index 0000000000..cabee7faad
--- /dev/null
+++ b/desktop/packages/mullvad-vpn/src/renderer/lib/icon-badge/IconBadge.tsx
@@ -0,0 +1,14 @@
+import { Image } from '../components';
+
+export interface IconBadgeProps {
+ state: 'positive' | 'negative';
+}
+
+const sources = {
+ positive: 'icon-success',
+ negative: 'icon-fail',
+};
+
+export const IconBadge = ({ state }: IconBadgeProps) => {
+ return <Image source={sources[state]} width={48} height={48} />;
+};
diff --git a/desktop/packages/mullvad-vpn/src/renderer/lib/icon-badge/index.ts b/desktop/packages/mullvad-vpn/src/renderer/lib/icon-badge/index.ts
new file mode 100644
index 0000000000..97a338a50a
--- /dev/null
+++ b/desktop/packages/mullvad-vpn/src/renderer/lib/icon-badge/index.ts
@@ -0,0 +1 @@
+export * from './IconBadge';