UNPKG

@blocklet/ui-react

Version:

Some useful front-end web components that can be used in Blocklets.

179 lines (155 loc) 5.62 kB
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, };