File size: 6,965 Bytes
921d377 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 | /**
* AboutDialog — professional "About HomePilot" popup window.
*
* Displays version, author, and project links in a centered modal overlay.
*/
import React, { useEffect, useRef } from 'react';
import { X, ExternalLink, Github, Globe, Heart, Activity } from 'lucide-react';
export default function AboutDialog({ onClose, onOpenSystemStatus }) {
const dialogRef = useRef(null);
// Close on Escape
useEffect(() => {
const handler = (e) => {
if (e.key === 'Escape')
onClose();
};
document.addEventListener('keydown', handler);
return () => document.removeEventListener('keydown', handler);
}, [onClose]);
// Close on backdrop click
const handleBackdropClick = (e) => {
if (e.target === e.currentTarget)
onClose();
};
return (<div className="fixed inset-0 z-[9999] flex items-center justify-center bg-black/60 backdrop-blur-sm" onClick={handleBackdropClick} style={{ animation: 'aboutFadeIn 200ms ease-out' }}>
<div ref={dialogRef} className="relative w-[420px] max-w-[92vw] bg-[#0c0c18] border border-white/10 rounded-3xl shadow-2xl overflow-hidden" style={{ animation: 'aboutSlideUp 250ms ease-out' }}>
{/* Close button */}
<button type="button" onClick={onClose} className="absolute top-4 right-4 z-10 h-8 w-8 rounded-full grid place-items-center text-white/40 hover:text-white hover:bg-white/10 transition-colors" aria-label="Close">
<X size={16}/>
</button>
{/* Top gradient accent */}
<div className="h-1.5 w-full bg-gradient-to-r from-purple-500 via-blue-500 to-cyan-400"/>
{/* Content */}
<div className="flex flex-col items-center px-8 pt-8 pb-6">
{/* Logo / Icon */}
<div className="relative mb-5">
<div className="w-20 h-20 rounded-2xl bg-gradient-to-br from-purple-600/30 to-blue-600/30 border border-white/10 grid place-items-center shadow-lg shadow-purple-500/10">
<svg width="44" height="44" viewBox="0 0 24 24" fill="none" stroke="url(#aboutGrad)" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round">
<defs>
<linearGradient id="aboutGrad" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" stopColor="#a855f7"/>
<stop offset="100%" stopColor="#06b6d4"/>
</linearGradient>
</defs>
<path d="M3 9l9-7 9 7v11a2 2 0 01-2 2H5a2 2 0 01-2-2z"/>
<polyline points="9 22 9 12 15 12 15 22"/>
</svg>
</div>
{/* Glow */}
<div className="absolute -inset-3 bg-purple-500/8 rounded-3xl blur-xl -z-10"/>
</div>
{/* Title */}
<h1 className="text-2xl font-bold text-white tracking-tight mb-0.5">
HomePilot
</h1>
{/* Version badge */}
<div className="flex items-center gap-2 mb-4">
<span className="px-2.5 py-0.5 text-xs font-semibold rounded-full bg-gradient-to-r from-purple-500/20 to-blue-500/20 text-purple-300 border border-purple-500/20">
v3.0.0
</span>
<span className="text-xs text-white/30">Home Edition</span>
</div>
{/* Description */}
<p className="text-[13px] text-white/50 text-center leading-relaxed max-w-[320px] mb-6">
The self-hosted AI platform with persistent identities, studio-grade content creation, and agentic tool access — running entirely on your hardware.
</p>
{/* Divider */}
<div className="w-full border-t border-white/5 mb-5"/>
{/* Info grid */}
<div className="w-full grid grid-cols-2 gap-3 text-[12px] mb-6">
<div className="bg-white/[0.03] rounded-xl px-3.5 py-2.5 border border-white/5">
<div className="text-white/30 mb-0.5">Developer</div>
<div className="text-white/80 font-medium">Ruslan Magana Vsevolodovna</div>
</div>
<div className="bg-white/[0.03] rounded-xl px-3.5 py-2.5 border border-white/5">
<div className="text-white/30 mb-0.5">License</div>
<div className="text-white/80 font-medium">Open Source</div>
</div>
<div className="bg-white/[0.03] rounded-xl px-3.5 py-2.5 border border-white/5">
<div className="text-white/30 mb-0.5">Stack</div>
<div className="text-white/80 font-medium">React + FastAPI</div>
</div>
<div className="bg-white/[0.03] rounded-xl px-3.5 py-2.5 border border-white/5">
<div className="text-white/30 mb-0.5">Architecture</div>
<div className="text-white/80 font-medium">160+ API Endpoints</div>
</div>
</div>
{/* Links */}
<div className="flex items-center gap-3 mb-5">
<a href="https://github.com/ruslanmv/HomePilot" target="_blank" rel="noopener noreferrer" className="flex items-center gap-1.5 px-3.5 py-2 rounded-xl bg-white/5 border border-white/8 text-white/70 hover:text-white hover:bg-white/10 transition-colors text-[12px] font-medium">
<Github size={14}/>
GitHub
<ExternalLink size={10} className="text-white/30"/>
</a>
<a href="https://ruslanmv.com/HomePilot/" target="_blank" rel="noopener noreferrer" className="flex items-center gap-1.5 px-3.5 py-2 rounded-xl bg-white/5 border border-white/8 text-white/70 hover:text-white hover:bg-white/10 transition-colors text-[12px] font-medium">
<Globe size={14}/>
Website
<ExternalLink size={10} className="text-white/30"/>
</a>
</div>
{/* Overview button */}
{onOpenSystemStatus && (<button type="button" onClick={() => { onClose(); onOpenSystemStatus(); }} className="flex items-center gap-1.5 px-3.5 py-2 rounded-xl bg-gradient-to-r from-emerald-500/10 to-cyan-500/10 border border-emerald-500/20 text-emerald-300 hover:text-white hover:border-emerald-400/30 transition-colors text-[12px] font-medium mb-5">
<Activity size={14}/>
Overview
</button>)}
{/* Footer */}
<div className="flex items-center gap-1.5 text-[11px] text-white/25">
<span>Made with</span>
<Heart size={10} className="text-red-400/60" fill="currentColor"/>
<span>by Ruslan Magana Vsevolodovna</span>
</div>
</div>
</div>
{/* Keyframe animations */}
<style>{`
@keyframes aboutFadeIn {
from { opacity: 0 }
to { opacity: 1 }
}
@keyframes aboutSlideUp {
from { opacity: 0; transform: translateY(16px) scale(0.97) }
to { opacity: 1; transform: translateY(0) scale(1) }
}
`}</style>
</div>);
}
|