用 Tailwind CSS 重写 Jwt 页面

This commit is contained in:
雨霖铃
2026-05-21 23:52:20 +08:00
parent 83bf9dd342
commit a4533be2c1
+31 -83
View File
@@ -1,7 +1,6 @@
import { useCallback, useMemo, useState } from 'react'; import { useCallback, useMemo, useState } from 'react';
import { Box, Container, Paper, Stack, Typography } from '@mui/material'; import { Key } from 'lucide-react';
import { useSnackbar } from '@/components/GlobalSnackbar'; import { useSnackbar } from '@/components/GlobalSnackbar';
import VpnKeyIcon from '@mui/icons-material/VpnKey';
import PageHeader from '@/components/PageHeader'; import PageHeader from '@/components/PageHeader';
import { stringifyJson, parseJwt } from '@/utils/jwt'; import { stringifyJson, parseJwt } from '@/utils/jwt';
import CopyButton from '@/components/CopyButton'; import CopyButton from '@/components/CopyButton';
@@ -18,42 +17,25 @@ interface SectionProps {
const Section = ({ title, content, color }: SectionProps) => { const Section = ({ title, content, color }: SectionProps) => {
const { t } = useLazyTranslation('jwt'); const { t } = useLazyTranslation('jwt');
return ( return (
<Paper <div
variant="outlined" className="p-4 rounded-xl border relative"
sx={{ style={{
p: 2,
borderRadius: 3,
borderColor: `${color}40`, borderColor: `${color}40`,
bgcolor: `${color}05`, backgroundColor: `${color}05`,
position: 'relative',
}} }}
> >
<Box sx={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', mb: 1 }}> <div className="flex justify-between items-center mb-2">
<Typography variant="subtitle2" sx={{ fontWeight: 800, color: color, letterSpacing: 0.5 }}> <span className="text-sm font-bold tracking-wide" style={{ color }}>
{title} {title}
</Typography> </span>
<Box sx={{ display: 'flex', gap: 0.5 }}> <div className="flex gap-1">
<CopyButton text={JSON.stringify(content)} size="small" /> <CopyButton text={JSON.stringify(content)} size="small" />
</Box> </div>
</Box> </div>
<Box <pre className="m-0 p-3 bg-white/60 rounded-lg text-xs font-mono overflow-x-auto whitespace-pre-wrap break-all border border-black/5">
component="pre"
sx={{
m: 0,
p: 1.5,
bgcolor: 'rgba(255,255,255,0.6)',
borderRadius: 2,
fontSize: '0.8rem',
fontFamily: 'monospace',
overflowX: 'auto',
whiteSpace: 'pre-wrap',
wordBreak: 'break-all',
border: '1px solid rgba(0,0,0,0.05)',
}}
>
{content ? stringifyJson(content) : t('jwt:invalidFormat')} {content ? stringifyJson(content) : t('jwt:invalidFormat')}
</Box> </pre>
</Paper> </div>
); );
}; };
@@ -77,15 +59,11 @@ export default function Index() {
}, [jwtInput]); }, [jwtInput]);
return ( return (
<Box> <div>
<Container sx={{ p: 2 }}> <div className="p-2">
<PageHeader <PageHeader title={t('jwt:pageTitle')} subtitle={t('jwt:pageSubtitle')} icon={<Key />} />
title={t('jwt:pageTitle')}
subtitle={t('jwt:pageSubtitle')}
icon={<VpnKeyIcon />}
/>
<Stack spacing={2.5}> <div className="flex flex-col gap-6">
{/* Input Area */} {/* Input Area */}
<TextInputArea <TextInputArea
minRows={4} minRows={4}
@@ -102,7 +80,7 @@ export default function Index() {
/> />
{result && !result.error && ( {result && !result.error && (
<Stack spacing={2}> <div className="flex flex-col gap-4">
<Section <Section
title={t('jwt:headerTitle')} title={t('jwt:headerTitle')}
content={result.header} content={result.header}
@@ -113,51 +91,21 @@ export default function Index() {
content={result.payload} content={result.payload}
color="#d63aff" // JWT.io Payload Color color="#d63aff" // JWT.io Payload Color
/> />
<Paper <div className="p-4 rounded-xl border border-blue-200 bg-blue-50">
variant="outlined" <div className="flex justify-between items-center mb-2">
sx={{ <span className="text-sm font-bold tracking-wide text-blue-600">
p: 2,
borderRadius: 3,
borderColor: 'primary.light',
bgcolor: 'primary.lighter',
}}
>
<Box
sx={{
display: 'flex',
justifyContent: 'space-between',
alignItems: 'center',
mb: 1,
}}
>
<Typography
variant="subtitle2"
sx={{ fontWeight: 800, color: 'info.main', letterSpacing: 0.5 }}
>
{t('jwt:signatureTitle')} {t('jwt:signatureTitle')}
</Typography> </span>
<CopyButton text={JSON.stringify(result.raw.signature)} size="small" /> <CopyButton text={JSON.stringify(result.raw.signature)} size="small" />
</Box> </div>
<Typography <span className="block text-sm font-mono break-all text-gray-500 bg-white/60 p-3 rounded-lg border border-black/5">
variant="body2"
sx={{
fontFamily: 'monospace',
fontSize: '0.8rem',
wordBreak: 'break-all',
color: 'text.secondary',
bgcolor: 'rgba(255,255,255,0.6)',
p: 1.5,
borderRadius: 2,
border: '1px solid rgba(0,0,0,0.05)',
}}
>
{result.signature || t('jwt:noSignature')} {result.signature || t('jwt:noSignature')}
</Typography> </span>
</Paper> </div>
</Stack> </div>
)} )}
</Stack> </div>
</Container> </div>
</Box> </div>
); );
} }