@blocklet/ui-react
Version:
Some useful front-end web components that can be used in Blocklets.
179 lines (155 loc) • 5.62 kB
JSX
import { useMemo, useState, useCallback } from 'react';
import PropTypes from 'prop-types';
import { Box, Typography, Button, Dialog, DialogActions, DialogContent } from '@mui/material';
import { useMemoizedFn } from 'ahooks';
import { translate } from '@arcblock/ux/lib/Locale/util';
import { joinURL } from 'ufo';
import useMobile from '../hooks/use-mobile';
const isAdmin = ['admin', 'owner'];
const isIpEcho = (hostname) => {
return hostname.endsWith('.ip.abtnet.io');
};
const isDidDomain = (hostname) => {
return hostname.endsWith('.did.abtnet.io');
};
const translations = {
en: {
guest: {
title: 'Notice: You are using a temporary domain',
description:
'You are accessing this site through a temporary domain. For a better experience, please contact the site administrator to configure a custom domain. Using a custom domain not only makes access more convenient but also ensures your access is more secure.',
},
owner: {
title: 'Enhance Your Website Security',
description: 'Dear administrator, we recommend configuring your custom domain immediately, which will:',
benefits1: 'Automatically obtain HTTPS certificates to ensure secure data transmission',
benefits2: 'Create an exclusive brand image and increase website credibility',
benefits3: 'Get a shorter, more memorable access address',
benefits4: 'Provide visitors with a more professional experience',
benefits5: 'Domain configuration takes just minutes to complete, taking your website to the next level!',
},
skip: 'Remind Me Later',
bindDomain: 'Configure Domain',
},
zh: {
guest: {
title: '温馨提示:当前使用的是临时域名',
description:
'您正在通过临时域名访问本站点。为了获得更好的访问体验,请联系站点管理员配置自定义域名。使用自定义域名不仅访问更便捷,还能确保您的访问更加安全。',
},
owner: {
title: '提升网站安全性与专业度',
description: '尊敬的管理员,我们建议您尽快配置自定义域名,这样可以:',
benefits1: '自动获取 HTTPS 证书,确保数据传输安全',
benefits2: '打造专属品牌形象,提升网站可信度',
benefits3: '获得更简短、易记的访问地址',
benefits4: '为访客提供更专业的访问体验',
benefits5: '只需几分钟即可完成域名配置,全面提升您的网站品质!',
},
skip: '稍后提醒',
bindDomain: '配置域名',
},
};
const ONE_MONTH = 1000 * 60 * 60 * 24 * 30;
const DASHBOARD_DOMAIN = '.well-known/service/admin/domains';
export default function DomainWarning({ locale = 'en', session = {} }) {
const user = session?.user;
const isMobile = useMobile();
const [open, setOpen] = useState(() => {
const skip = window.localStorage.getItem('domain-warning-skip');
if (!skip) return true;
const now = +new Date();
const skipTime = +new Date(skip);
return now - skipTime > ONE_MONTH;
});
const t = useMemoizedFn((key, data = {}) => {
return translate(translations, key, locale, 'en', data);
});
const host = useMemo(() => {
try {
const { hostname } = new URL(window.location.href);
return hostname;
} catch (error) {
return '';
}
}, []);
const benefits = useMemo(
() => [
t('owner.benefits1'),
t('owner.benefits2'),
t('owner.benefits3'),
t('owner.benefits4'),
t('owner.benefits5'),
],
[t]
);
const handleSkip = useCallback(() => {
window.localStorage.setItem('domain-warning-skip', new Date().toISOString());
setOpen(false);
}, []);
const handleDomainConfig = useCallback(() => {
const adminUrl = joinURL(window.location.origin, DASHBOARD_DOMAIN);
if (adminUrl.startsWith('http')) {
window.open(adminUrl, '_blank');
}
setOpen(false);
}, []);
const isOwner = user?.role && isAdmin.includes(user.role);
if (window.location.href.includes(DASHBOARD_DOMAIN)) {
return null;
}
if (isMobile) {
return null;
}
if (!isIpEcho(host) && !isDidDomain(host)) {
return null;
}
return (
<Dialog open={open} disableEscapeKeyDown fullWidth maxWidth="sm" onClose={() => setOpen(false)}>
<DialogContent sx={{ padding: '20px !important' }}>
<Typography
sx={{
fontSize: '20px',
fontWeight: '500',
}}>
{isOwner ? t('owner.title') : t('guest.title')}
</Typography>
<Typography
sx={{
marginTop: '20px',
fontSize: '14px',
color: 'text.secondary',
}}>
{isOwner ? t('owner.description') : t('guest.description')}
</Typography>
{isOwner && (
<Box component="ul">
{benefits.map((benefit) => (
<Typography
component="li"
key={benefit}
sx={{
fontSize: '14px',
color: 'text.secondary',
}}>
{benefit}
</Typography>
))}
</Box>
)}
</DialogContent>
<DialogActions sx={{ px: '12px !important' }}>
<Button onClick={handleSkip}>{t('skip')}</Button>
{isOwner && (
<Button variant="contained" onClick={handleDomainConfig}>
{t('bindDomain')}
</Button>
)}
</DialogActions>
</Dialog>
);
}
DomainWarning.propTypes = {
locale: PropTypes.string,
session: PropTypes.object,
};