chore: remove debug logging and disable debug mode for production
- Removed temporary console logs used for debugging - Disabled DEBUG_MODE flag - Updated configuration to run in production mode - Cleaned up leftover debug utilities to reduce noise in console
This commit is contained in:
320
src/components/ui/ComparisonTable.jsx
Normal file
320
src/components/ui/ComparisonTable.jsx
Normal file
@@ -0,0 +1,320 @@
|
||||
|
||||
|
||||
|
||||
const ComparisonTable = () => {
|
||||
const [selectedFeature, setSelectedFeature] = React.useState(null);
|
||||
|
||||
const messengers = [
|
||||
{
|
||||
name: "SecureBit.chat",
|
||||
logo: <div className="w-8 h-8 bg-orange-500/10 border border-orange-500/20 rounded-lg flex items-center justify-center">
|
||||
<i className="fas fa-shield-halved text-orange-400" />
|
||||
</div>,
|
||||
type: "P2P WebRTC",
|
||||
version: "Latest",
|
||||
color: "orange",
|
||||
},
|
||||
{
|
||||
name: "Signal",
|
||||
logo: (
|
||||
<svg className="w-8 h-8" viewBox="0 0 122.88 122.31" xmlns="http://www.w3.org/2000/svg">
|
||||
<path className="fill-blue-500" d="M27.75,0H95.13a27.83,27.83,0,0,1,27.75,27.75V94.57a27.83,27.83,0,0,1-27.75,27.74H27.75A27.83,27.83,0,0,1,0,94.57V27.75A27.83,27.83,0,0,1,27.75,0Z" />
|
||||
<path className="fill-white" d="M61.44,25.39A35.76,35.76,0,0,0,31.18,80.18L27.74,94.86l14.67-3.44a35.77,35.77,0,1,0,19-66Z" />
|
||||
</svg>
|
||||
),
|
||||
type: "Centralized",
|
||||
version: "Latest",
|
||||
color: "blue",
|
||||
},
|
||||
{
|
||||
name: "Threema",
|
||||
logo: (
|
||||
<svg className="w-8 h-8" viewBox="0 0 122.88 122.88" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect width="122.88" height="122.88" rx="18.43" fill="#474747" />
|
||||
<path fill="#FFFFFF" d="M44.26,78.48l-19.44,4.8l4.08-16.56c-4.08-5.28-6.48-12-6.48-18.96c0-18.96,17.52-34.32,39.12-34.32c21.6,0,39.12,15.36,39.12,34.32c0,18.96-17.52,34.32-39.12,34.32c-6,0-12-1.2-17.04-3.36L44.26,78.48z M50.26,44.64h-0.48c-0.96,0-1.68,0.72-1.44,1.68v15.6c0,0.96,0.72,1.68,1.68,1.68l23.04,0c0.96,0,1.68-0.72,1.68-1.68v-15.6c0-0.96-0.72-1.68-1.68-1.68h-0.48v-4.32c0-6-5.04-11.04-11.04-11.04S50.5,34.32,50.5,40.32v4.32H50.26z M68.02,44.64h-13.2v-4.32c0-3.6,2.88-6.72,6.72-6.72c3.6,0,6.72,2.88,6.72,6.72v4.32H68.02z" />
|
||||
<circle cx="37.44" cy="97.44" r="6.72" fill="#3fe669" />
|
||||
<circle cx="61.44" cy="97.44" r="6.72" fill="#3fe669" />
|
||||
<circle cx="85.44" cy="97.44" r="6.72" fill="#3fe669" />
|
||||
</svg>
|
||||
),
|
||||
type: "Centralized",
|
||||
version: "Latest",
|
||||
color: "green",
|
||||
},
|
||||
{
|
||||
name: "Session",
|
||||
logo: (
|
||||
<svg className="w-8 h-8" viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect width="1024" height="1024" fill="#333132" />
|
||||
<path fill="#00f782" d="M431 574.8c-.8-7.4-6.7-8.2-10.8-10.6-13.6-7.9-27.5-15.4-41.3-23l-22.5-12.3c-8.5-4.7-17.1-9.2-25.6-14.1-10.5-6-21-11.9-31.1-18.6-18.9-12.5-33.8-29.1-46.3-48.1-8.3-12.6-14.8-26.1-19.2-40.4-6.7-21.7-10.8-44.1-7.8-66.8 1.8-14 4.6-28 9.7-41.6 7.8-20.8 19.3-38.8 34.2-54.8 9.8-10.6 21.2-19.1 33.4-26.8 14.7-9.3 30.7-15.4 47.4-19 13.8-3 28.1-4.3 42.2-4.4 89.9-.4 179.7-.3 269.6 0 12.6 0 25.5 1 37.7 4.1 24.3 6.2 45.7 18.2 63 37 11.2 12.2 20.4 25.8 25.8 41.2 7.3 20.7 12.3 42.1 6.7 64.4-2.1 8.5-2.7 17.5-6.1 25.4-4.7 10.9-10.8 21.2-17.2 31.2-8.7 13.5-20.5 24.3-34.4 32.2-10.1 5.7-21 10.2-32 14.3-18.1 6.7-37.2 5-56.1 5.2-17.2.2-34.5 0-51.7.1-1.7 0-3.4 1.2-5.1 1.9 1.3 1.8 2.1 4.3 3.9 5.3 13.5 7.8 27.2 15.4 40.8 22.9 11 6 22.3 11.7 33.2 17.9 15.2 8.5 30.2 17.4 45.3 26.1 19.3 11.1 34.8 26.4 47.8 44.3 9.7 13.3 17.2 27.9 23 43.5 6.1 16.6 9.2 33.8 10.4 51.3.6 9.1-.7 18.5-1.9 27.6-1.2 9.1-2.7 18.4-5.6 27.1-3.3 10.2-7.4 20.2-12.4 29.6-8.4 15.7-19.6 29.4-32.8 41.4-12.7 11.5-26.8 20.6-42.4 27.6-22.9 10.3-46.9 14.4-71.6 14.5-89.7.3-179.4.2-269.1-.1-12.6 0-25.5-1-37.7-3.9-24.5-5.7-45.8-18-63.3-36.4-11.6-12.3-20.2-26.5-26.6-41.9-2.7-6.4-4.1-13.5-5.4-20.4-1.5-8.1-2.8-16.3-3.1-24.5-.6-15.7 2.8-30.9 8.2-45.4 8.2-22 21.7-40.6 40.2-55.2 10-7.9 21.3-13.7 33.1-18.8 16.6-7.2 34-8.1 51.4-8.5 21.9-.5 43.9-.1 65.9-.1 1.9-.1 3.9-.3 6.2-.4zm96.3-342.4c0 .1 0 .1 0 0-48.3.1-96.6-.6-144.9.5-13.5.3-27.4 3.9-40.1 8.7-14.9 5.6-28.1 14.6-39.9 25.8-20.2 19-32.2 42.2-37.2 68.9-3.6 19-1.4 38.1 4.1 56.5 4.1 13.7 10.5 26.4 18.5 38.4 14.8 22.2 35.7 36.7 58.4 49.2 11 6.1 22.2 11.9 33.2 18 13.5 7.5 26.9 15.1 40.4 22.6 13.1 7.3 26.2 14.5 39.2 21.7 9.7 5.3 19.4 10.7 29.1 16.1 2.9 1.6 4.1.2 4.5-2.4.3-2 .3-4 .3-6.1v-58.8c0-19.9.1-39.9 0-59.8 0-6.6 1.7-12.8 7.6-16.1 3.5-2 8.2-2.8 12.4-2.8 50.3-.2 100.7-.2 151-.1 19.8 0 38.3-4.4 55.1-15.1 23.1-14.8 36.3-36.3 40.6-62.9 3.4-20.8-1-40.9-12.4-58.5-17.8-27.5-43.6-43-76.5-43.6-47.8-.8-95.6-.2-143.4-.2zm-30.6 559.7c45.1 0 90.2-.2 135.3.1 18.9.1 36.6-3.9 53.9-11.1 18.4-7.7 33.6-19.8 46.3-34.9 9.1-10.8 16.2-22.9 20.8-36.5 4.2-12.4 7.4-24.7 7.3-37.9-.1-10.3.2-20.5-3.4-30.5-2.6-7.2-3.4-15.2-6.4-22.1-3.9-8.9-8.9-17.3-14-25.5-12.9-20.8-31.9-34.7-52.8-46.4-10.6-5.9-21.2-11.6-31.8-17.5-10.3-5.7-20.4-11.7-30.7-17.4-11.2-6.1-22.5-11.9-33.7-18-16.6-9.1-33.1-18.4-49.8-27.5-4.9-2.7-6.1-1.9-6.4 3.9-.1 2-.1 4.1-.1 6.1v114.5c0 14.8-5.6 20.4-20.4 20.4-47.6.1-95.3-.1-142.9.2-10.5.1-21.1 1.4-31.6 2.8-16.5 2.2-30.5 9.9-42.8 21-17 15.5-27 34.7-29.4 57.5-1.1 10.9-.4 21.7 2.9 32.5 3.7 12.3 9.2 23.4 17.5 33 19.2 22.1 43.4 33.3 72.7 33.3 46.6.1 93 0 139.5 0z" />
|
||||
</svg>
|
||||
),
|
||||
type: "Onion Network",
|
||||
version: "Latest",
|
||||
color: "cyan",
|
||||
},
|
||||
];
|
||||
|
||||
const features = [
|
||||
{
|
||||
name: "Security Architecture",
|
||||
lockbit: { status: "trophy", detail: "18-layer military-grade defense system with complete ASN.1 validation" },
|
||||
signal: { status: "check", detail: "Signal Protocol with double ratchet" },
|
||||
threema: { status: "check", detail: "Standard security implementation" },
|
||||
session: { status: "check", detail: "Modified Signal Protocol + Onion routing" },
|
||||
},
|
||||
{
|
||||
name: "Cryptography",
|
||||
lockbit: { status: "trophy", detail: "ECDH P-384 + AES-GCM 256 + ECDSA P-384" },
|
||||
signal: { status: "check", detail: "Signal Protocol + Double Ratchet" },
|
||||
threema: { status: "check", detail: "NaCl + XSalsa20 + Poly1305" },
|
||||
session: { status: "check", detail: "Modified Signal Protocol" },
|
||||
},
|
||||
{
|
||||
name: "Perfect Forward Secrecy",
|
||||
lockbit: { status: "trophy", detail: "Auto rotation every 5 minutes or 100 messages" },
|
||||
signal: { status: "check", detail: "Double Ratchet algorithm" },
|
||||
threema: { status: "warning", detail: "Partial (group chats)" },
|
||||
session: { status: "check", detail: "Session Ratchet algorithm" },
|
||||
},
|
||||
{
|
||||
name: "Architecture",
|
||||
lockbit: { status: "trophy", detail: "Pure P2P WebRTC without servers" },
|
||||
signal: { status: "times", detail: "Centralized Signal servers" },
|
||||
threema: { status: "times", detail: "Threema servers in Switzerland" },
|
||||
session: { status: "warning", detail: "Onion routing via network nodes" },
|
||||
},
|
||||
{
|
||||
name: "Registration Anonymity",
|
||||
lockbit: { status: "trophy", detail: "No registration required, instant anonymous channels" },
|
||||
signal: { status: "times", detail: "Phone number required" },
|
||||
threema: { status: "check", detail: "ID generated locally" },
|
||||
session: { status: "check", detail: "Random session ID" },
|
||||
},
|
||||
{
|
||||
name: "Payment Integration",
|
||||
lockbit: { status: "trophy", detail: "Lightning Network satoshis per session + WebLN" },
|
||||
signal: { status: "times", detail: "No payment system" },
|
||||
threema: { status: "times", detail: "No payment system" },
|
||||
session: { status: "times", detail: "No payment system" },
|
||||
},
|
||||
{
|
||||
name: "Metadata Protection",
|
||||
lockbit: { status: "trophy", detail: "Full metadata encryption + traffic obfuscation" },
|
||||
signal: { status: "warning", detail: "Sealed Sender (partial)" },
|
||||
threema: { status: "warning", detail: "Minimal metadata" },
|
||||
session: { status: "check", detail: "Onion routing hides metadata" },
|
||||
},
|
||||
{
|
||||
name: "Traffic Obfuscation",
|
||||
lockbit: { status: "trophy", detail: "Fake traffic + pattern masking + packet padding" },
|
||||
signal: { status: "times", detail: "No traffic obfuscation" },
|
||||
threema: { status: "times", detail: "No traffic obfuscation" },
|
||||
session: { status: "check", detail: "Onion routing provides obfuscation" },
|
||||
},
|
||||
{
|
||||
name: "Open Source",
|
||||
lockbit: { status: "trophy", detail: "100% open + auditable + MIT license" },
|
||||
signal: { status: "check", detail: "Fully open" },
|
||||
threema: { status: "warning", detail: "Only clients open" },
|
||||
session: { status: "check", detail: "Fully open" },
|
||||
},
|
||||
{
|
||||
name: "MITM Protection",
|
||||
lockbit: { status: "trophy", detail: "Out-of-band verification + mutual auth + ECDSA" },
|
||||
signal: { status: "check", detail: "Safety numbers verification" },
|
||||
threema: { status: "check", detail: "QR code scanning" },
|
||||
session: { status: "warning", detail: "Basic key verification" },
|
||||
},
|
||||
{
|
||||
name: "Economic Model",
|
||||
lockbit: { status: "trophy", detail: "Sustainable pay-per-session model" },
|
||||
signal: { status: "warning", detail: "Donations and grants dependency" },
|
||||
threema: { status: "check", detail: "One-time app purchase" },
|
||||
session: { status: "warning", detail: "Donations dependency" },
|
||||
},
|
||||
{
|
||||
name: "Censorship Resistance",
|
||||
lockbit: { status: "trophy", detail: "Impossible to block P2P + no servers to target" },
|
||||
signal: { status: "warning", detail: "Blocked in authoritarian countries" },
|
||||
threema: { status: "warning", detail: "May be blocked" },
|
||||
session: { status: "check", detail: "Onion routing bypasses blocks" },
|
||||
},
|
||||
{
|
||||
name: "Data Storage",
|
||||
lockbit: { status: "trophy", detail: "Zero data storage - only in browser memory" },
|
||||
signal: { status: "warning", detail: "Local database storage" },
|
||||
threema: { status: "warning", detail: "Local + optional backup" },
|
||||
session: { status: "warning", detail: "Local database storage" },
|
||||
},
|
||||
{
|
||||
name: "Key Security",
|
||||
lockbit: { status: "trophy", detail: "Non-extractable keys + hardware protection" },
|
||||
signal: { status: "check", detail: "Secure key storage" },
|
||||
threema: { status: "check", detail: "Local key storage" },
|
||||
session: { status: "check", detail: "Secure key storage" },
|
||||
},
|
||||
{
|
||||
name: "Post-Quantum Roadmap",
|
||||
lockbit: { status: "check", detail: "Planned v5.0 - CRYSTALS-Kyber/Dilithium" },
|
||||
signal: { status: "warning", detail: "PQXDH in development" },
|
||||
threema: { status: "times", detail: "Not announced" },
|
||||
session: { status: "times", detail: "Not announced" },
|
||||
},
|
||||
];
|
||||
|
||||
const getStatusIcon = (status) => {
|
||||
const statusMap = {
|
||||
"trophy": { icon: "fa-trophy", color: "accent-orange" },
|
||||
"check": { icon: "fa-check", color: "text-green-300" },
|
||||
"warning": { icon: "fa-exclamation-triangle", color: "text-yellow-300" },
|
||||
"times": { icon: "fa-times", color: "text-red-300" },
|
||||
};
|
||||
return statusMap[status] || { icon: "fa-question", color: "text-gray-400" };
|
||||
};
|
||||
|
||||
const toggleFeatureDetail = (index) => {
|
||||
setSelectedFeature(selectedFeature === index ? null : index);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="mt-16">
|
||||
{/* Title */}
|
||||
<div className="text-center mb-8">
|
||||
<h3 className="text-3xl font-bold text-white mb-3">
|
||||
Enhanced Security Edition Comparison
|
||||
</h3>
|
||||
<p className="text-gray-400 max-w-2xl mx-auto mb-4">
|
||||
Enhanced Security Edition vs leading secure messengers
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{/* Table container */}
|
||||
<div className="max-w-7xl mx-auto">
|
||||
{/* Mobile Alert */}
|
||||
<div className="md:hidden p-4 bg-yellow-500/10 border border-yellow-500/20 rounded-lg mb-4">
|
||||
<p className="text-yellow-400 text-sm text-center">
|
||||
<i className="fas fa-lightbulb mr-2"></i>
|
||||
Rotate your device horizontally for better viewing
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{/* Table */}
|
||||
<div className="overflow-x-auto">
|
||||
<table
|
||||
className="w-full border-collapse rounded-xl overflow-hidden shadow-2xl"
|
||||
style={{ backgroundColor: "rgba(42, 43, 42, 0.9)" }}
|
||||
>
|
||||
{/* Table Header */}
|
||||
<thead>
|
||||
<tr className="bg-black-table">
|
||||
<th className="text-left p-4 border-b border-gray-600 text-white font-bold min-w-[240px]">
|
||||
Security Criterion
|
||||
</th>
|
||||
{messengers.map((messenger, index) => (
|
||||
<th key={`messenger-${index}`} className="text-center p-4 border-b border-gray-600 min-w-[160px]">
|
||||
<div className="flex flex-col items-center">
|
||||
<div className="mb-2">{messenger.logo}</div>
|
||||
<div className={`text-sm font-bold ${
|
||||
messenger.color === 'orange' ? 'text-orange-400' :
|
||||
messenger.color === 'blue' ? 'text-blue-400' :
|
||||
messenger.color === 'green' ? 'text-green-400' :
|
||||
'text-cyan-400'
|
||||
}`}>
|
||||
{messenger.name}
|
||||
</div>
|
||||
<div className="text-xs text-gray-400">{messenger.type}</div>
|
||||
<div className="text-xs text-gray-500 mt-1">{messenger.version}</div>
|
||||
</div>
|
||||
</th>
|
||||
))}
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
{/* Table body */}
|
||||
<tbody>
|
||||
{features.map((feature, featureIndex) => (
|
||||
<React.Fragment key={`feature-${featureIndex}`}>
|
||||
<tr
|
||||
className={`border-b border-gray-700/30 transition-all duration-200 cursor-pointer hover:bg-[rgb(20_20_20_/30%)] ${
|
||||
selectedFeature === featureIndex ? 'bg-[rgb(20_20_20_/50%)]' : ''
|
||||
}`}
|
||||
onClick={() => toggleFeatureDetail(featureIndex)}
|
||||
>
|
||||
<td className="p-4 text-white font-semibold">
|
||||
<div className="flex items-center justify-between">
|
||||
<span>{feature.name}</span>
|
||||
<i className={`fas fa-chevron-${selectedFeature === featureIndex ? 'up' : 'down'} text-xs text-gray-400 opacity-60 transition-all duration-200`} />
|
||||
</div>
|
||||
</td>
|
||||
<td className="p-4 text-center">
|
||||
<i className={`fas ${getStatusIcon(feature.lockbit.status).icon} ${getStatusIcon(feature.lockbit.status).color} text-2xl`} />
|
||||
</td>
|
||||
<td className="p-4 text-center">
|
||||
<i className={`fas ${getStatusIcon(feature.signal.status).icon} ${getStatusIcon(feature.signal.status).color} text-2xl`} />
|
||||
</td>
|
||||
<td className="p-4 text-center">
|
||||
<i className={`fas ${getStatusIcon(feature.threema.status).icon} ${getStatusIcon(feature.threema.status).color} text-2xl`} />
|
||||
</td>
|
||||
<td className="p-4 text-center">
|
||||
<i className={`fas ${getStatusIcon(feature.session.status).icon} ${getStatusIcon(feature.session.status).color} text-2xl`} />
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
{/* Details */}
|
||||
{selectedFeature === featureIndex && (
|
||||
<tr className="border-b border-gray-700/30 bg-gradient-to-r from-gray-800/20 to-gray-900/20">
|
||||
<td className="p-4 text-xs text-gray-400 font-medium">Technical Details:</td>
|
||||
<td className="p-4 text-center">
|
||||
<div className="text-xs text-orange-300 font-medium leading-relaxed">
|
||||
{feature.lockbit.detail}
|
||||
</div>
|
||||
</td>
|
||||
<td className="p-4 text-center">
|
||||
<div className="text-xs text-blue-300 leading-relaxed">
|
||||
{feature.signal.detail}
|
||||
</div>
|
||||
</td>
|
||||
<td className="p-4 text-center">
|
||||
<div className="text-xs text-green-300 leading-relaxed">
|
||||
{feature.threema.detail}
|
||||
</div>
|
||||
</td>
|
||||
<td className="p-4 text-center">
|
||||
<div className="text-xs text-cyan-300 leading-relaxed">
|
||||
{feature.session.detail}
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
)}
|
||||
</React.Fragment>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
{/* Legend */}
|
||||
<div className="mt-8 grid grid-cols-2 md:grid-cols-4 gap-4 max-w-5xl mx-auto">
|
||||
<div className="flex items-center justify-center p-4 bg-orange-500/10 rounded-xl hover:bg-orange-500/40 transition-colors">
|
||||
<i className="fas fa-trophy text-orange-400 mr-2 text-xl"></i>
|
||||
<span className="text-orange-300 text-sm font-bold">Category Leader</span>
|
||||
</div>
|
||||
|
||||
<div className="flex items-center justify-center p-4 bg-green-500/10 rounded-xl hover:bg-green-600/40 transition-colors">
|
||||
<i className="fas fa-check text-green-300 mr-2 text-xl"></i>
|
||||
<span className="text-green-200 text-sm font-bold">Excellent</span>
|
||||
</div>
|
||||
<div className="flex items-center justify-center p-4 bg-yellow-500/10 rounded-xl hover:bg-yellow-600/40 transition-colors">
|
||||
<i className="fas fa-exclamation-triangle text-yellow-300 mr-2 text-xl"></i>
|
||||
<span className="text-yellow-200 text-sm font-bold">Partial/Limited</span>
|
||||
</div>
|
||||
<div className="flex items-center justify-center p-4 bg-red-500/10 rounded-xl hover:bg-red-600/40 transition-colors">
|
||||
<i className="fas fa-times text-red-300 mr-2 text-xl"></i>
|
||||
<span className="text-red-200 text-sm font-bold">Not Available</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
window.ComparisonTable = ComparisonTable;
|
||||
@@ -53,19 +53,6 @@ const EnhancedMinimalHeader = ({
|
||||
realSecurityData = await window.EnhancedSecureCryptoUtils.calculateSecurityLevel(activeWebrtcManager);
|
||||
}
|
||||
|
||||
if (window.DEBUG_MODE) {
|
||||
console.log('🔐 REAL security level calculated:', {
|
||||
level: realSecurityData?.level,
|
||||
score: realSecurityData?.score,
|
||||
passedChecks: realSecurityData?.passedChecks,
|
||||
totalChecks: realSecurityData?.totalChecks,
|
||||
isRealData: realSecurityData?.isRealData,
|
||||
sessionType: realSecurityData?.sessionType,
|
||||
maxPossibleScore: realSecurityData?.maxPossibleScore,
|
||||
verificationResults: realSecurityData?.verificationResults ? Object.keys(realSecurityData.verificationResults) : []
|
||||
});
|
||||
}
|
||||
|
||||
if (realSecurityData && realSecurityData.isRealData !== false) {
|
||||
const currentScore = realSecurityLevel?.score || 0;
|
||||
const newScore = realSecurityData.score || 0;
|
||||
@@ -73,23 +60,15 @@ const EnhancedMinimalHeader = ({
|
||||
if (currentScore !== newScore || !realSecurityLevel) {
|
||||
setRealSecurityLevel(realSecurityData);
|
||||
setLastSecurityUpdate(now);
|
||||
|
||||
if (window.DEBUG_MODE) {
|
||||
console.log('✅ Security level updated in header component:', {
|
||||
oldScore: currentScore,
|
||||
newScore: newScore,
|
||||
sessionType: realSecurityData.sessionType
|
||||
});
|
||||
}
|
||||
} else if (window.DEBUG_MODE) {
|
||||
console.log('ℹ️ Security level unchanged, skipping update');
|
||||
|
||||
} else if (window.DEBUG_MODE) {
|
||||
}
|
||||
} else {
|
||||
console.warn('⚠️ Security calculation returned invalid data');
|
||||
console.warn(' Security calculation returned invalid data');
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
console.error('❌ Error in real security calculation:', error);
|
||||
console.error(' Error in real security calculation:', error);
|
||||
} finally {
|
||||
isUpdating = false;
|
||||
}
|
||||
@@ -122,9 +101,6 @@ const EnhancedMinimalHeader = ({
|
||||
|
||||
React.useEffect(() => {
|
||||
const handleSecurityUpdate = (event) => {
|
||||
if (window.DEBUG_MODE) {
|
||||
console.log('🔒 Security level update event received:', event.detail);
|
||||
}
|
||||
|
||||
setTimeout(() => {
|
||||
setLastSecurityUpdate(0);
|
||||
@@ -132,9 +108,6 @@ const EnhancedMinimalHeader = ({
|
||||
};
|
||||
|
||||
const handleRealSecurityCalculated = (event) => {
|
||||
if (window.DEBUG_MODE) {
|
||||
console.log('🔐 Real security calculated event:', event.detail);
|
||||
}
|
||||
|
||||
if (event.detail && event.detail.securityData) {
|
||||
setRealSecurityLevel(event.detail.securityData);
|
||||
@@ -146,9 +119,6 @@ const EnhancedMinimalHeader = ({
|
||||
document.addEventListener('real-security-calculated', handleRealSecurityCalculated);
|
||||
|
||||
window.forceHeaderSecurityUpdate = (webrtcManager) => {
|
||||
if (window.DEBUG_MODE) {
|
||||
console.log('🔄 Force header security update called');
|
||||
}
|
||||
|
||||
if (webrtcManager && window.EnhancedSecureCryptoUtils) {
|
||||
window.EnhancedSecureCryptoUtils.calculateSecurityLevel(webrtcManager)
|
||||
@@ -223,9 +193,6 @@ const EnhancedMinimalHeader = ({
|
||||
};
|
||||
|
||||
const handleDisconnected = () => {
|
||||
if (window.DEBUG_MODE) {
|
||||
console.log('🔌 Disconnected - clearing security data in header');
|
||||
}
|
||||
|
||||
setRealSecurityLevel(null);
|
||||
setLastSecurityUpdate(0);
|
||||
@@ -264,19 +231,11 @@ const EnhancedMinimalHeader = ({
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
|
||||
// Debug information
|
||||
console.log('🔍 Security click debug:', {
|
||||
hasWebrtcManager: !!webrtcManager,
|
||||
hasCryptoUtils: !!window.EnhancedSecureCryptoUtils,
|
||||
hasRealSecurityLevel: !!realSecurityLevel,
|
||||
connectionStatus: webrtcManager?.connectionState || 'unknown'
|
||||
});
|
||||
|
||||
// Run real security tests if webrtcManager is available
|
||||
let realTestResults = null;
|
||||
if (webrtcManager && window.EnhancedSecureCryptoUtils) {
|
||||
try {
|
||||
console.log('🔍 Running real security tests...');
|
||||
realTestResults = await window.EnhancedSecureCryptoUtils.calculateSecurityLevel(webrtcManager);
|
||||
console.log('✅ Real security tests completed:', realTestResults);
|
||||
} catch (error) {
|
||||
@@ -312,11 +271,11 @@ const EnhancedMinimalHeader = ({
|
||||
totalChecks: 0,
|
||||
sessionType: 'unknown'
|
||||
};
|
||||
console.log('⚠️ Using fallback security data:', securityData);
|
||||
console.log('Using fallback security data:', securityData);
|
||||
}
|
||||
|
||||
// Detailed information about the REAL security check
|
||||
let message = `🔒 REAL-TIME SECURITY VERIFICATION\n\n`;
|
||||
let message = `REAL-TIME SECURITY VERIFICATION\n\n`;
|
||||
message += `Security Level: ${securityData.level} (${securityData.score}%)\n`;
|
||||
message += `Session Type: ${securityData.sessionType || 'premium'}\n`;
|
||||
message += `Verification Time: ${new Date(securityData.timestamp).toLocaleTimeString()}\n`;
|
||||
@@ -330,7 +289,7 @@ const EnhancedMinimalHeader = ({
|
||||
const failedTests = Object.entries(securityData.verificationResults).filter(([key, result]) => !result.passed);
|
||||
|
||||
if (passedTests.length > 0) {
|
||||
message += '✅ PASSED TESTS:\n';
|
||||
message += 'PASSED TESTS:\n';
|
||||
passedTests.forEach(([key, result]) => {
|
||||
const testName = key.replace(/([A-Z])/g, ' $1').replace(/^./, str => str.toUpperCase());
|
||||
message += ` ${testName}: ${result.details || 'Test passed'}\n`;
|
||||
@@ -339,7 +298,7 @@ const EnhancedMinimalHeader = ({
|
||||
}
|
||||
|
||||
if (failedTests.length > 0) {
|
||||
message += '❌ FAILED/UNAVAILABLE TESTS:\n';
|
||||
message += 'FAILED/UNAVAILABLE TESTS:\n';
|
||||
failedTests.forEach(([key, result]) => {
|
||||
const testName = key.replace(/([A-Z])/g, ' $1').replace(/^./, str => str.toUpperCase());
|
||||
message += ` ${testName}: ${result.details || 'Test failed or unavailable'}\n`;
|
||||
@@ -353,7 +312,7 @@ const EnhancedMinimalHeader = ({
|
||||
}
|
||||
|
||||
// Real security features status
|
||||
message += `🔒 SECURITY FEATURES STATUS:\n`;
|
||||
message += `SECURITY FEATURES STATUS:\n`;
|
||||
message += '=' + '='.repeat(40) + '\n';
|
||||
|
||||
if (securityData.verificationResults) {
|
||||
|
||||
432
src/components/ui/Roadmap.jsx
Normal file
432
src/components/ui/Roadmap.jsx
Normal file
@@ -0,0 +1,432 @@
|
||||
function Roadmap() {
|
||||
const [selectedPhase, setSelectedPhase] = React.useState(null);
|
||||
const phases = [
|
||||
{
|
||||
version: "v1.0",
|
||||
title: "Start of Development",
|
||||
status: "done",
|
||||
date: "Early 2025",
|
||||
description: "Idea, prototype, and infrastructure setup",
|
||||
features: [
|
||||
"Concept and requirements formation",
|
||||
"Stack selection: WebRTC, P2P, cryptography",
|
||||
"First messaging prototypes",
|
||||
"Repository creation and CI",
|
||||
"Basic encryption architecture",
|
||||
"UX/UI design"
|
||||
]
|
||||
},
|
||||
{
|
||||
version: "v1.5",
|
||||
title: "Alpha Release",
|
||||
status: "done",
|
||||
date: "Spring 2025",
|
||||
description: "First public alpha: basic chat and key exchange",
|
||||
features: [
|
||||
"Basic P2P messaging via WebRTC",
|
||||
"Simple E2E encryption (demo scheme)",
|
||||
"Stable signaling and reconnection",
|
||||
"Minimal UX for testing",
|
||||
"Feedback collection from early testers"
|
||||
]
|
||||
},
|
||||
{
|
||||
version: "v2.0",
|
||||
title: "Security Hardened",
|
||||
status: "done",
|
||||
date: "Summer 2025",
|
||||
description: "Security strengthening and stable branch release",
|
||||
features: [
|
||||
"ECDH/ECDSA implementation in production",
|
||||
"Perfect Forward Secrecy and key rotation",
|
||||
"Improved authentication checks",
|
||||
"File encryption and large payload transfers",
|
||||
"Audit of basic cryptoprocesses"
|
||||
]
|
||||
},
|
||||
{
|
||||
version: "v3.0",
|
||||
title: "Scaling & Stability",
|
||||
status: "done",
|
||||
date: "Fall 2025",
|
||||
description: "Network scaling and stability improvements",
|
||||
features: [
|
||||
"Optimization of P2P connections and NAT traversal",
|
||||
"Reconnection mechanisms and message queues",
|
||||
"Reduced battery consumption on mobile",
|
||||
"Support for multi-device synchronization",
|
||||
"Monitoring and logging tools for developers"
|
||||
]
|
||||
},
|
||||
{
|
||||
version: "v3.5",
|
||||
title: "Privacy-first Release",
|
||||
status: "done",
|
||||
date: "Winter 2025",
|
||||
description: "Focus on privacy: minimizing metadata",
|
||||
features: [
|
||||
"Metadata protection and fingerprint reduction",
|
||||
"Experiments with onion routing and DHT",
|
||||
"Options for anonymous connections",
|
||||
"Preparation for open code audit",
|
||||
"Improved user verification processes"
|
||||
]
|
||||
},
|
||||
|
||||
// current and future phases
|
||||
{
|
||||
version: "v4.2.12",
|
||||
title: "Enhanced Security Edition",
|
||||
status: "current",
|
||||
date: "Now",
|
||||
description: "Current version with ECDH + DTLS + SAS security, 18-layer military-grade cryptography and complete ASN.1 validation",
|
||||
features: [
|
||||
"ECDH + DTLS + SAS triple-layer security",
|
||||
"ECDH P-384 + AES-GCM 256-bit encryption",
|
||||
"DTLS fingerprint verification",
|
||||
"SAS (Short Authentication String) verification",
|
||||
"Perfect Forward Secrecy with key rotation",
|
||||
"Enhanced MITM attack prevention",
|
||||
"Complete ASN.1 DER validation",
|
||||
"OID and EC point verification",
|
||||
"SPKI structure validation",
|
||||
"P2P WebRTC architecture",
|
||||
"Metadata protection",
|
||||
"100% open source code"
|
||||
]
|
||||
},
|
||||
{
|
||||
version: "v4.5",
|
||||
title: "Mobile & Desktop Edition",
|
||||
status: "development",
|
||||
date: "Q2 2025",
|
||||
description: "Native apps for all platforms",
|
||||
features: [
|
||||
"PWA app for mobile",
|
||||
"Electron app for desktop",
|
||||
"Real-time notifications",
|
||||
"Automatic reconnection",
|
||||
"Battery optimization",
|
||||
"Cross-device synchronization",
|
||||
"Improved UX/UI",
|
||||
"Support for files up to 100MB"
|
||||
]
|
||||
},
|
||||
{
|
||||
version: "v5.0",
|
||||
title: "Quantum-Resistant Edition",
|
||||
status: "planned",
|
||||
date: "Q4 2025",
|
||||
description: "Protection against quantum computers",
|
||||
features: [
|
||||
"Post-quantum cryptography CRYSTALS-Kyber",
|
||||
"SPHINCS+ digital signatures",
|
||||
"Hybrid scheme: classic + PQ",
|
||||
"Quantum-safe key exchange",
|
||||
"Updated hashing algorithms",
|
||||
"Migration of existing sessions",
|
||||
"Compatibility with v4.x",
|
||||
"Quantum-resistant protocols"
|
||||
]
|
||||
},
|
||||
{
|
||||
version: "v5.5",
|
||||
title: "Group Communications",
|
||||
status: "planned",
|
||||
date: "Q2 2026",
|
||||
description: "Group chats with preserved privacy",
|
||||
features: [
|
||||
"P2P group connections up to 8 participants",
|
||||
"Mesh networking for groups",
|
||||
"Signal Double Ratchet for groups",
|
||||
"Anonymous groups without metadata",
|
||||
"Ephemeral groups (disappear after session)",
|
||||
"Cryptographic group administration",
|
||||
"Group member auditing"
|
||||
]
|
||||
},
|
||||
{
|
||||
version: "v6.0",
|
||||
title: "Decentralized Network",
|
||||
status: "research",
|
||||
date: "2027",
|
||||
description: "Fully decentralized network",
|
||||
features: [
|
||||
"LockBit node mesh network",
|
||||
"DHT for peer discovery",
|
||||
"Built-in onion routing",
|
||||
"Tokenomics and node incentives",
|
||||
"Governance via DAO",
|
||||
"Interoperability with other networks",
|
||||
"Cross-platform compatibility",
|
||||
"Self-healing network"
|
||||
]
|
||||
},
|
||||
{
|
||||
version: "v7.0",
|
||||
title: "AI Privacy Assistant",
|
||||
status: "research",
|
||||
date: "2028+",
|
||||
description: "AI for privacy and security",
|
||||
features: [
|
||||
"Local AI threat analysis",
|
||||
"Automatic MITM detection",
|
||||
"Adaptive cryptography",
|
||||
"Personalized security recommendations",
|
||||
"Zero-knowledge machine learning",
|
||||
"Private AI assistant",
|
||||
"Predictive security",
|
||||
"Autonomous attack protection"
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
|
||||
const getStatusConfig = (status) => {
|
||||
switch (status) {
|
||||
case 'current':
|
||||
return {
|
||||
color: 'green',
|
||||
bgClass: 'bg-green-500/10 border-green-500/20',
|
||||
textClass: 'text-green-400',
|
||||
icon: 'fas fa-check-circle',
|
||||
label: 'Current Version'
|
||||
};
|
||||
case 'development':
|
||||
return {
|
||||
color: 'orange',
|
||||
bgClass: 'bg-orange-500/10 border-orange-500/20',
|
||||
textClass: 'text-orange-400',
|
||||
icon: 'fas fa-code',
|
||||
label: 'In Development'
|
||||
};
|
||||
case 'planned':
|
||||
return {
|
||||
color: 'blue',
|
||||
bgClass: 'bg-blue-500/10 border-blue-500/20',
|
||||
textClass: 'text-blue-400',
|
||||
icon: 'fas fa-calendar-alt',
|
||||
label: 'Planned'
|
||||
};
|
||||
case 'research':
|
||||
return {
|
||||
color: 'purple',
|
||||
bgClass: 'bg-purple-500/10 border-purple-500/20',
|
||||
textClass: 'text-purple-400',
|
||||
icon: 'fas fa-flask',
|
||||
label: 'Research'
|
||||
};
|
||||
case 'done':
|
||||
return {
|
||||
color: 'gray',
|
||||
bgClass: 'bg-gray-500/10 border-gray-500/20',
|
||||
textClass: 'text-gray-300',
|
||||
icon: 'fas fa-flag-checkered',
|
||||
label: 'Released'
|
||||
};
|
||||
default:
|
||||
return {
|
||||
color: 'gray',
|
||||
bgClass: 'bg-gray-500/10 border-gray-500/20',
|
||||
textClass: 'text-gray-400',
|
||||
icon: 'fas fa-question',
|
||||
label: 'Unknown'
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
const togglePhaseDetail = (index) => {
|
||||
setSelectedPhase(selectedPhase === index ? null : index);
|
||||
};
|
||||
return (
|
||||
<div key="roadmap-section" className="mt-16 px-4 sm:px-0">
|
||||
<div key="section-header" className="text-center mb-12">
|
||||
<h3 key="title" className="text-2xl font-semibold text-primary mb-3">
|
||||
Development Roadmap
|
||||
</h3>
|
||||
<p key="subtitle" className="text-secondary max-w-2xl mx-auto mb-6">
|
||||
Evolution of SecureBit.chat : from initial development to quantum-resistant decentralized network with complete ASN.1 validation
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div key="roadmap-container" className="max-w-6xl mx-auto">
|
||||
<div key="timeline" className="relative">
|
||||
{/* The line has been removed */}
|
||||
|
||||
<div key="phases" className="space-y-8">
|
||||
{phases.map((phase, index) => {
|
||||
const statusConfig = getStatusConfig(phase.status);
|
||||
const isExpanded = selectedPhase === index;
|
||||
|
||||
return (
|
||||
<div key={`phase-${index}`} className="relative">
|
||||
{/* The dots are visible only on sm and larger screens */}
|
||||
|
||||
<button
|
||||
type="button"
|
||||
aria-expanded={isExpanded}
|
||||
onClick={() => togglePhaseDetail(index)}
|
||||
key={`phase-button-${index}`}
|
||||
className={`card-minimal rounded-xl p-4 text-left w-full transition-all duration-300 ${
|
||||
isExpanded
|
||||
? "ring-2 ring-" + statusConfig.color + "-500/30"
|
||||
: ""
|
||||
}`}
|
||||
>
|
||||
<div
|
||||
key="phase-header"
|
||||
className="flex flex-col sm:flex-row sm:items-center sm:justify-between mb-4 space-y-2 sm:space-y-0"
|
||||
>
|
||||
<div
|
||||
key="phase-info"
|
||||
className="flex flex-col sm:flex-row sm:items-center sm:space-x-4"
|
||||
>
|
||||
<div
|
||||
key="version-badge"
|
||||
className={`px-3 py-1 ${statusConfig.bgClass} border rounded-lg mb-2 sm:mb-0`}
|
||||
>
|
||||
<span
|
||||
key="version"
|
||||
className={`${statusConfig.textClass} font-bold text-sm`}
|
||||
>
|
||||
{phase.version}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div key="title-section">
|
||||
<h4
|
||||
key="title"
|
||||
className="text-lg font-semibold text-primary"
|
||||
>
|
||||
{phase.title}
|
||||
</h4>
|
||||
<p
|
||||
key="description"
|
||||
className="text-secondary text-sm"
|
||||
>
|
||||
{phase.description}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
key="phase-meta"
|
||||
className="flex items-center space-x-3 text-sm text-gray-400 font-medium"
|
||||
>
|
||||
<div
|
||||
key="status-badge"
|
||||
className={`flex items-center px-3 py-1 ${statusConfig.bgClass} border rounded-lg`}
|
||||
>
|
||||
<i
|
||||
key="status-icon"
|
||||
className={`${statusConfig.icon} ${statusConfig.textClass} mr-2 text-xs`}
|
||||
/>
|
||||
<span
|
||||
key="status-text"
|
||||
className={`${statusConfig.textClass} text-xs font-medium`}
|
||||
>
|
||||
{statusConfig.label}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div key="date">{phase.date}</div>
|
||||
<i
|
||||
key="expand-icon"
|
||||
className={`fas fa-chevron-${
|
||||
isExpanded ? "up" : "down"
|
||||
} text-gray-400 text-sm`}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{isExpanded && (
|
||||
<div
|
||||
key="features-section"
|
||||
className="mt-6 pt-6 border-t border-gray-700/30"
|
||||
>
|
||||
<h5
|
||||
key="features-title"
|
||||
className="text-primary font-medium mb-4 flex items-center"
|
||||
>
|
||||
<i
|
||||
key="features-icon"
|
||||
className="fas fa-list-ul mr-2 text-sm"
|
||||
/>
|
||||
Key features:
|
||||
</h5>
|
||||
|
||||
<div
|
||||
key="features-grid"
|
||||
className="grid md:grid-cols-2 gap-3"
|
||||
>
|
||||
{phase.features.map((feature, featureIndex) => (
|
||||
<div
|
||||
key={`feature-${featureIndex}`}
|
||||
className="flex items-center space-x-3 p-3 bg-custom-bg rounded-lg"
|
||||
>
|
||||
<div
|
||||
className={`w-2 h-2 rounded-full ${statusConfig.textClass.replace(
|
||||
"text-",
|
||||
"bg-"
|
||||
)}`}
|
||||
/>
|
||||
<span className="text-secondary text-sm">
|
||||
{feature}
|
||||
</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div key="cta-section" className="mt-12 text-center">
|
||||
<div
|
||||
key="cta-card"
|
||||
className="card-minimal rounded-xl p-8 max-w-2xl mx-auto"
|
||||
>
|
||||
<h4
|
||||
key="cta-title"
|
||||
className="text-xl font-semibold text-primary mb-3"
|
||||
>
|
||||
Join the future of privacy
|
||||
</h4>
|
||||
<p key="cta-description" className="text-secondary mb-6">
|
||||
SecureBit.chat grows thanks to the community. Your ideas and feedback help shape the future of secure communication with complete ASN.1 validation.
|
||||
</p>
|
||||
|
||||
<div
|
||||
key="cta-buttons"
|
||||
className="flex flex-col sm:flex-row gap-4 justify-center"
|
||||
>
|
||||
<a
|
||||
key="github-link"
|
||||
href="https://github.com/SecureBitChat/securebit-chat/"
|
||||
className="btn-primary text-white py-3 px-6 rounded-lg font-medium transition-all duration-200 flex items-center justify-center"
|
||||
>
|
||||
<i key="github-icon" className="fab fa-github mr-2" />
|
||||
GitHub Repository
|
||||
</a>
|
||||
|
||||
<a
|
||||
key="feedback-link"
|
||||
href="mailto:lockbitchat@tutanota.com"
|
||||
className="btn-secondary text-white py-3 px-6 rounded-lg font-medium transition-all duration-200 flex items-center justify-center"
|
||||
>
|
||||
<i key="feedback-icon" className="fas fa-comments mr-2" />
|
||||
Feedback
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
window.Roadmap = Roadmap;
|
||||
168
src/components/ui/UniqueFeatureSlider.jsx
Normal file
168
src/components/ui/UniqueFeatureSlider.jsx
Normal file
@@ -0,0 +1,168 @@
|
||||
// Slider Component
|
||||
const UniqueFeatureSlider = () => {
|
||||
const [currentSlide, setCurrentSlide] = React.useState(0);
|
||||
|
||||
const slides = [
|
||||
{
|
||||
icon: "fas fa-shield-halved",
|
||||
color: "orange",
|
||||
title: "18-Layer Military Security",
|
||||
description: "Revolutionary defense system with ECDH P-384 + AES-GCM 256 + ECDSA + Complete ASN.1 Validation. Enhanced Security Edition provides military-grade protection exceeding government standards with complete key structure verification."
|
||||
},
|
||||
{
|
||||
icon: "fas fa-network-wired",
|
||||
color: "purple",
|
||||
title: "Pure P2P WebRTC Architecture",
|
||||
description: "Direct peer-to-peer connections without any servers. Impossible to censor, block, or monitor. Complete decentralization with zero infrastructure."
|
||||
},
|
||||
{
|
||||
icon: "fas fa-sync-alt",
|
||||
color: "green",
|
||||
title: "Perfect Forward Secrecy",
|
||||
description: "Automatic key rotation every 5 minutes or 100 messages. Non-extractable keys with hardware protection ensure past messages remain secure."
|
||||
},
|
||||
{
|
||||
icon: "fas fa-user-secret",
|
||||
color: "cyan",
|
||||
title: "Advanced Traffic Obfuscation",
|
||||
description: "Fake traffic generation, packet padding, and pattern masking make communication indistinguishable from random noise. Defeats traffic analysis."
|
||||
},
|
||||
{
|
||||
icon: "fas fa-eye-slash",
|
||||
color: "blue",
|
||||
title: "Zero Data Collection",
|
||||
description: "No registration, no servers, no logs. Messages exist only in browser memory. Complete anonymity with instant anonymous channels."
|
||||
},
|
||||
{
|
||||
icon: "fas fa-code",
|
||||
color: "emerald",
|
||||
title: "100% Open Source Security",
|
||||
description: "All code is open for audit under MIT license. Uses only standard WebCrypto APIs. Cryptography runs directly in browser without server dependencies."
|
||||
}
|
||||
];
|
||||
|
||||
const nextSlide = () => setCurrentSlide((prev) => (prev + 1) % slides.length);
|
||||
const prevSlide = () => setCurrentSlide((prev) => (prev - 1 + slides.length) % slides.length);
|
||||
const goToSlide = (index) => setCurrentSlide(index);
|
||||
|
||||
React.useEffect(() => {
|
||||
const timer = setInterval(() => {
|
||||
nextSlide();
|
||||
}, 15000);
|
||||
return () => clearInterval(timer);
|
||||
}, []);
|
||||
|
||||
return React.createElement('div', {
|
||||
className: "mt-12"
|
||||
}, [
|
||||
React.createElement('div', {
|
||||
key: 'header',
|
||||
className: "text-center mb-8"
|
||||
}, [
|
||||
React.createElement('h3', {
|
||||
key: 'title',
|
||||
className: "text-2xl font-semibold text-primary mb-3"
|
||||
}, 'Why SecureBit.chat is unique'),
|
||||
React.createElement('p', {
|
||||
key: 'subtitle',
|
||||
className: "text-secondary max-w-2xl mx-auto"
|
||||
}, 'The only messenger with military-grade cryptography')
|
||||
]),
|
||||
|
||||
React.createElement('div', {
|
||||
key: 'slider-container',
|
||||
className: "relative max-w-4xl mx-auto"
|
||||
}, [
|
||||
React.createElement('div', {
|
||||
key: 'slider-wrapper',
|
||||
className: "overflow-hidden rounded-xl"
|
||||
}, [
|
||||
React.createElement('div', {
|
||||
key: 'slides',
|
||||
className: "flex transition-transform duration-500 ease-in-out",
|
||||
style: { transform: `translateX(-${currentSlide * 100}%)` }
|
||||
}, slides.map((slide, index) =>
|
||||
React.createElement('div', {
|
||||
key: index,
|
||||
className: "w-full flex-shrink-0 px-4"
|
||||
}, [
|
||||
React.createElement('div', {
|
||||
key: 'slide-content',
|
||||
className: "card-minimal rounded-xl p-8 text-center min-h-[300px] flex flex-col justify-center relative overflow-hidden"
|
||||
}, [
|
||||
// Background icon
|
||||
React.createElement('i', {
|
||||
key: 'bg-icon',
|
||||
className: `${slide.icon} absolute right-[-100px] top-1/2 -translate-y-1/2 opacity-10 text-[300px] pointer-events-none ${
|
||||
slide.color === 'orange' ? 'text-orange-500' :
|
||||
slide.color === 'yellow' ? 'text-yellow-500' :
|
||||
slide.color === 'purple' ? 'text-purple-500' :
|
||||
slide.color === 'green' ? 'text-green-500' :
|
||||
slide.color === 'cyan' ? 'text-cyan-500' :
|
||||
slide.color === 'blue' ? 'text-blue-500' :
|
||||
'text-emerald-500'
|
||||
}`
|
||||
}),
|
||||
|
||||
// Content
|
||||
React.createElement('h4', {
|
||||
key: 'slide-title',
|
||||
className: "text-xl font-semibold text-primary mb-4 relative z-10"
|
||||
}, slide.title),
|
||||
React.createElement('p', {
|
||||
key: 'slide-description',
|
||||
className: "text-secondary leading-relaxed max-w-2xl mx-auto relative z-10"
|
||||
}, slide.description)
|
||||
])
|
||||
])
|
||||
))
|
||||
]),
|
||||
|
||||
// Navigation
|
||||
React.createElement('button', {
|
||||
key: 'prev-btn',
|
||||
onClick: prevSlide,
|
||||
className: "absolute left-2 top-1/2 transform -translate-y-1/2 w-10 h-10 bg-gray-600/80 hover:bg-gray-500/80 text-white rounded-full flex items-center justify-center transition-all duration-200 z-10"
|
||||
}, [
|
||||
React.createElement('i', {
|
||||
key: 'prev-icon',
|
||||
className: "fas fa-chevron-left"
|
||||
})
|
||||
]),
|
||||
React.createElement('button', {
|
||||
key: 'next-btn',
|
||||
onClick: nextSlide,
|
||||
className: "absolute right-2 top-1/2 transform -translate-y-1/2 w-10 h-10 bg-gray-600/80 hover:bg-gray-500/80 text-white rounded-full flex items-center justify-center transition-all duration-200 z-10"
|
||||
}, [
|
||||
React.createElement('i', {
|
||||
key: 'next-icon',
|
||||
className: "fas fa-chevron-right"
|
||||
})
|
||||
])
|
||||
]),
|
||||
|
||||
// Enhanced dots navigation (оставляем улучшенные точки)
|
||||
React.createElement('div', {
|
||||
key: 'dots-container',
|
||||
className: "flex justify-center space-x-3 mt-6"
|
||||
}, slides.map((slide, index) =>
|
||||
React.createElement('button', {
|
||||
key: index,
|
||||
onClick: () => goToSlide(index),
|
||||
className: `relative group transition-all duration-300 ${
|
||||
index === currentSlide
|
||||
? 'w-12 h-2 bg-orange-500 rounded-full'
|
||||
: 'w-4 h-2 bg-gray-600 hover:bg-gray-500 rounded-full hover:scale-125'
|
||||
}`
|
||||
}, [
|
||||
// Tooltip on hover
|
||||
React.createElement('div', {
|
||||
key: 'tooltip',
|
||||
className: "absolute -top-10 left-1/2 transform -translate-x-1/2 bg-gray-800 text-white text-xs px-2 py-1 rounded opacity-0 group-hover:opacity-100 transition-opacity duration-200 whitespace-nowrap pointer-events-none"
|
||||
}, slide.title)
|
||||
])
|
||||
))
|
||||
]);
|
||||
};
|
||||
|
||||
window.UniqueFeatureSlider = UniqueFeatureSlider;
|
||||
Reference in New Issue
Block a user