style: replace emojis with text indicators in UI components

- SecurityWarning: replace emoji icons with text-based indicators
- NodeModal: minor formatting cleanup
This commit is contained in:
rcourtman 2025-12-13 21:30:44 +00:00
parent 7eb6d33dad
commit 7891027d55
2 changed files with 81 additions and 87 deletions

View file

@ -92,11 +92,11 @@ export const SecurityWarning: Component = () => {
return 'text-red-600 dark:text-red-400'; return 'text-red-600 dark:text-red-400';
}; };
const getScoreEmoji = (score: number, max: number) => { const getScoreIcon = (score: number, max: number) => {
const percentage = (score / max) * 100; const percentage = (score / max) * 100;
if (percentage >= 80) return '🛡️'; if (percentage >= 80) return 'shield';
if (percentage >= 60) return '⚠️'; if (percentage >= 60) return 'warning';
return '🚨'; return 'alert';
}; };
// Show more aggressively if public access detected // Show more aggressively if public access detected
@ -120,8 +120,7 @@ export const SecurityWarning: Component = () => {
return ( return (
<Portal> <Portal>
<div <div
class={`fixed top-0 left-0 right-0 z-50 border-b shadow-sm ${ class={`fixed top-0 left-0 right-0 z-50 border-b shadow-sm ${status()!.publicAccess && !status()!.hasAuthentication
status()!.publicAccess && !status()!.hasAuthentication
? 'bg-red-50 dark:bg-red-900/20 border-red-200 dark:border-red-800' ? 'bg-red-50 dark:bg-red-900/20 border-red-200 dark:border-red-800'
: 'bg-yellow-50 dark:bg-yellow-900/20 border-yellow-200 dark:border-yellow-800' : 'bg-yellow-50 dark:bg-yellow-900/20 border-yellow-200 dark:border-yellow-800'
}`} }`}
@ -129,7 +128,9 @@ export const SecurityWarning: Component = () => {
<div class="max-w-7xl mx-auto px-4 py-3"> <div class="max-w-7xl mx-auto px-4 py-3">
<div class="flex items-start justify-between"> <div class="flex items-start justify-between">
<div class="flex items-start space-x-3"> <div class="flex items-start space-x-3">
<span class="text-2xl">{getScoreEmoji(status()!.score, status()!.maxScore)}</span> <span class={`text-2xl ${getScoreIcon(status()!.score, status()!.maxScore) === 'shield' ? 'text-green-600' : getScoreIcon(status()!.score, status()!.maxScore) === 'warning' ? 'text-yellow-600' : 'text-red-600'}`}>
{getScoreIcon(status()!.score, status()!.maxScore) === 'shield' ? '✓' : getScoreIcon(status()!.score, status()!.maxScore) === 'warning' ? '!' : '!!'}
</span>
<div> <div>
<div class="flex items-center gap-3"> <div class="flex items-center gap-3">
<SectionHeader <SectionHeader
@ -157,7 +158,7 @@ export const SecurityWarning: Component = () => {
<p class="text-sm text-gray-700 dark:text-gray-300 mt-1"> <p class="text-sm text-gray-700 dark:text-gray-300 mt-1">
{status()!.publicAccess ? ( {status()!.publicAccess ? (
<span class="font-semibold text-red-700 dark:text-red-300"> <span class="font-semibold text-red-700 dark:text-red-300">
PUBLIC NETWORK ACCESS DETECTED - Your Proxmox credentials are exposed to WARNING: PUBLIC NETWORK ACCESS DETECTED - Your Proxmox credentials are exposed to
the internet! the internet!
</span> </span>
) : ( ) : (
@ -172,13 +173,13 @@ export const SecurityWarning: Component = () => {
<span <span
class={status()!.credentialsEncrypted ? 'text-green-600' : 'text-red-600'} class={status()!.credentialsEncrypted ? 'text-green-600' : 'text-red-600'}
> >
{status()!.credentialsEncrypted ? '✅' : '❌'} {status()!.credentialsEncrypted ? 'Yes' : 'No'}
</span> </span>
<span>Credentials encrypted at rest</span> <span>Credentials encrypted at rest</span>
</div> </div>
<div class="flex items-center gap-2"> <div class="flex items-center gap-2">
<span class={status()!.exportProtected ? 'text-green-600' : 'text-red-600'}> <span class={status()!.exportProtected ? 'text-green-600' : 'text-red-600'}>
{status()!.exportProtected ? '✅' : '❌'} {status()!.exportProtected ? 'Yes' : 'No'}
</span> </span>
<span>Export requires authentication</span> <span>Export requires authentication</span>
</div> </div>
@ -186,19 +187,19 @@ export const SecurityWarning: Component = () => {
<span <span
class={status()!.hasAuthentication ? 'text-green-600' : 'text-red-600'} class={status()!.hasAuthentication ? 'text-green-600' : 'text-red-600'}
> >
{status()!.hasAuthentication ? '✅' : '❌'} {status()!.hasAuthentication ? 'Yes' : 'No'}
</span> </span>
<span>Authentication enabled</span> <span>Authentication enabled</span>
</div> </div>
<div class="flex items-center gap-2"> <div class="flex items-center gap-2">
<span class={status()!.hasHTTPS ? 'text-green-600' : 'text-red-600'}> <span class={status()!.hasHTTPS ? 'text-green-600' : 'text-red-600'}>
{status()!.hasHTTPS ? '✅' : '❌'} {status()!.hasHTTPS ? 'Yes' : 'No'}
</span> </span>
<span>HTTPS connection</span> <span>HTTPS connection</span>
</div> </div>
<div class="flex items-center gap-2"> <div class="flex items-center gap-2">
<span class={status()!.hasAuditLogging ? 'text-green-600' : 'text-red-600'}> <span class={status()!.hasAuditLogging ? 'text-green-600' : 'text-red-600'}>
{status()!.hasAuditLogging ? '✅' : '❌'} {status()!.hasAuditLogging ? 'Yes' : 'No'}
</span> </span>
<span>Audit logging enabled</span> <span>Audit logging enabled</span>
</div> </div>

View file

@ -776,8 +776,7 @@ export const NodeModal: Component<NodeModalProps> = (props) => {
<button <button
type="button" type="button"
onClick={() => updateField('setupMode', 'agent')} onClick={() => updateField('setupMode', 'agent')}
class={`inline-flex items-center px-3 py-1.5 text-sm font-medium rounded-md border border-transparent transition-colors ${ class={`inline-flex items-center px-3 py-1.5 text-sm font-medium rounded-md border border-transparent transition-colors ${formData().setupMode === 'agent'
formData().setupMode === 'agent'
? 'bg-white dark:bg-gray-800 text-blue-600 dark:text-blue-300 border-gray-300 dark:border-gray-600 shadow-sm' ? 'bg-white dark:bg-gray-800 text-blue-600 dark:text-blue-300 border-gray-300 dark:border-gray-600 shadow-sm'
: 'text-gray-600 dark:text-gray-400 hover:text-blue-600 dark:hover:text-blue-300 hover:bg-gray-200/60 dark:hover:bg-gray-700/60' : 'text-gray-600 dark:text-gray-400 hover:text-blue-600 dark:hover:text-blue-300 hover:bg-gray-200/60 dark:hover:bg-gray-700/60'
}`} }`}
@ -790,8 +789,7 @@ export const NodeModal: Component<NodeModalProps> = (props) => {
<button <button
type="button" type="button"
onClick={() => updateField('setupMode', 'auto')} onClick={() => updateField('setupMode', 'auto')}
class={`inline-flex items-center px-3 py-1.5 text-sm font-medium rounded-md border border-transparent transition-colors ${ class={`inline-flex items-center px-3 py-1.5 text-sm font-medium rounded-md border border-transparent transition-colors ${formData().setupMode === 'auto'
formData().setupMode === 'auto'
? 'bg-white dark:bg-gray-800 text-blue-600 dark:text-blue-300 border-gray-300 dark:border-gray-600 shadow-sm' ? 'bg-white dark:bg-gray-800 text-blue-600 dark:text-blue-300 border-gray-300 dark:border-gray-600 shadow-sm'
: 'text-gray-600 dark:text-gray-400 hover:text-blue-600 dark:hover:text-blue-300 hover:bg-gray-200/60 dark:hover:bg-gray-700/60' : 'text-gray-600 dark:text-gray-400 hover:text-blue-600 dark:hover:text-blue-300 hover:bg-gray-200/60 dark:hover:bg-gray-700/60'
}`} }`}
@ -801,8 +799,7 @@ export const NodeModal: Component<NodeModalProps> = (props) => {
<button <button
type="button" type="button"
onClick={() => updateField('setupMode', 'manual')} onClick={() => updateField('setupMode', 'manual')}
class={`inline-flex items-center px-3 py-1.5 text-sm font-medium rounded-md border border-transparent transition-colors ${ class={`inline-flex items-center px-3 py-1.5 text-sm font-medium rounded-md border border-transparent transition-colors ${formData().setupMode === 'manual'
formData().setupMode === 'manual'
? 'bg-white dark:bg-gray-800 text-blue-600 dark:text-blue-300 border-gray-300 dark:border-gray-600 shadow-sm' ? 'bg-white dark:bg-gray-800 text-blue-600 dark:text-blue-300 border-gray-300 dark:border-gray-600 shadow-sm'
: 'text-gray-600 dark:text-gray-400 hover:text-blue-600 dark:hover:text-blue-300 hover:bg-gray-200/60 dark:hover:bg-gray-700/60' : 'text-gray-600 dark:text-gray-400 hover:text-blue-600 dark:hover:text-blue-300 hover:bg-gray-200/60 dark:hover:bg-gray-700/60'
}`} }`}
@ -1007,7 +1004,7 @@ export const NodeModal: Component<NodeModalProps> = (props) => {
<code class="text-blue-400"> <code class="text-blue-400">
{formData().host {formData().host
? 'Click the button above to copy the setup command' ? 'Click the button above to copy the setup command'
: '⚠️ Please enter the Host URL above first'} : 'Please enter the Host URL above first'}
</code> </code>
} }
> >
@ -1153,7 +1150,7 @@ export const NodeModal: Component<NodeModalProps> = (props) => {
</li> </li>
</ul> </ul>
<p class="text-xs text-green-600 dark:text-green-400 mt-2 font-semibold"> <p class="text-xs text-green-600 dark:text-green-400 mt-2 font-semibold">
Fully automatic - no manual token copying needed! Fully automatic - no manual token copying needed!
</p> </p>
</div> </div>
</Show> </Show>
@ -1252,7 +1249,7 @@ export const NodeModal: Component<NodeModalProps> = (props) => {
</code> </code>
</div> </div>
<p class="text-amber-600 dark:text-amber-400 text-xs mt-1"> <p class="text-amber-600 dark:text-amber-400 text-xs mt-1">
Copy the token value immediately - it won't be shown again! Important: Copy the token value immediately - it won't be shown again!
</p> </p>
</div> </div>
@ -1337,7 +1334,7 @@ export const NodeModal: Component<NodeModalProps> = (props) => {
</code> </code>
</div> </div>
<p class="text-gray-600 dark:text-gray-400 text-xs mt-1"> <p class="text-gray-600 dark:text-gray-400 text-xs mt-1">
PVEAuditor gives read-only API access. PulseMonitor adds Note: PVEAuditor gives read-only API access. PulseMonitor adds
Sys.Audit plus either VM.Monitor (PVE 8) or VM.GuestAgent.Audit Sys.Audit plus either VM.Monitor (PVE 8) or VM.GuestAgent.Audit
(PVE 9+) for disk and guest metrics. PVEDatastoreAdmin on (PVE 9+) for disk and guest metrics. PVEDatastoreAdmin on
/storage adds backup visibility. /storage adds backup visibility.
@ -1374,8 +1371,7 @@ export const NodeModal: Component<NodeModalProps> = (props) => {
<button <button
type="button" type="button"
onClick={() => updateField('setupMode', 'agent')} onClick={() => updateField('setupMode', 'agent')}
class={`inline-flex items-center gap-1.5 px-3 py-1.5 text-sm font-medium rounded-md border border-transparent transition-colors ${ class={`inline-flex items-center gap-1.5 px-3 py-1.5 text-sm font-medium rounded-md border border-transparent transition-colors ${formData().setupMode === 'agent'
formData().setupMode === 'agent'
? 'bg-white dark:bg-gray-800 text-blue-600 dark:text-blue-300 border-gray-300 dark:border-gray-600 shadow-sm' ? 'bg-white dark:bg-gray-800 text-blue-600 dark:text-blue-300 border-gray-300 dark:border-gray-600 shadow-sm'
: 'text-gray-600 dark:text-gray-400 hover:text-blue-600 dark:hover:text-blue-300 hover:bg-gray-200/60 dark:hover:bg-gray-700/60' : 'text-gray-600 dark:text-gray-400 hover:text-blue-600 dark:hover:text-blue-300 hover:bg-gray-200/60 dark:hover:bg-gray-700/60'
}`} }`}
@ -1386,8 +1382,7 @@ export const NodeModal: Component<NodeModalProps> = (props) => {
<button <button
type="button" type="button"
onClick={() => updateField('setupMode', 'auto')} onClick={() => updateField('setupMode', 'auto')}
class={`inline-flex items-center px-3 py-1.5 text-sm font-medium rounded-md border border-transparent transition-colors ${ class={`inline-flex items-center px-3 py-1.5 text-sm font-medium rounded-md border border-transparent transition-colors ${formData().setupMode === 'auto'
formData().setupMode === 'auto'
? 'bg-white dark:bg-gray-800 text-blue-600 dark:text-blue-300 border-gray-300 dark:border-gray-600 shadow-sm' ? 'bg-white dark:bg-gray-800 text-blue-600 dark:text-blue-300 border-gray-300 dark:border-gray-600 shadow-sm'
: 'text-gray-600 dark:text-gray-400 hover:text-blue-600 dark:hover:text-blue-300 hover:bg-gray-200/60 dark:hover:bg-gray-700/60' : 'text-gray-600 dark:text-gray-400 hover:text-blue-600 dark:hover:text-blue-300 hover:bg-gray-200/60 dark:hover:bg-gray-700/60'
}`} }`}
@ -1397,8 +1392,7 @@ export const NodeModal: Component<NodeModalProps> = (props) => {
<button <button
type="button" type="button"
onClick={() => updateField('setupMode', 'manual')} onClick={() => updateField('setupMode', 'manual')}
class={`inline-flex items-center px-3 py-1.5 text-sm font-medium rounded-md border border-transparent transition-colors ${ class={`inline-flex items-center px-3 py-1.5 text-sm font-medium rounded-md border border-transparent transition-colors ${formData().setupMode === 'manual'
formData().setupMode === 'manual'
? 'bg-white dark:bg-gray-800 text-blue-600 dark:text-blue-300 border-gray-300 dark:border-gray-600 shadow-sm' ? 'bg-white dark:bg-gray-800 text-blue-600 dark:text-blue-300 border-gray-300 dark:border-gray-600 shadow-sm'
: 'text-gray-600 dark:text-gray-400 hover:text-blue-600 dark:hover:text-blue-300 hover:bg-gray-200/60 dark:hover:bg-gray-700/60' : 'text-gray-600 dark:text-gray-400 hover:text-blue-600 dark:hover:text-blue-300 hover:bg-gray-200/60 dark:hover:bg-gray-700/60'
}`} }`}
@ -2261,8 +2255,7 @@ export const NodeModal: Component<NodeModalProps> = (props) => {
return null; return null;
})()} })()}
<div <div
class={`mx-6 p-3 rounded-lg text-sm ${ class={`mx-6 p-3 rounded-lg text-sm ${testResult()?.status === 'success'
testResult()?.status === 'success'
? 'bg-green-50 dark:bg-green-900/20 border border-green-200 dark:border-green-800 text-green-800 dark:text-green-200' ? 'bg-green-50 dark:bg-green-900/20 border border-green-200 dark:border-green-800 text-green-800 dark:text-green-200'
: testResult()?.status === 'warning' : testResult()?.status === 'warning'
? 'bg-amber-50 dark:bg-amber-900/20 border border-amber-200 dark:border-amber-800 text-amber-800 dark:text-amber-200' ? 'bg-amber-50 dark:bg-amber-900/20 border border-amber-200 dark:border-amber-800 text-amber-800 dark:text-amber-200'