// ============================================================================
// wifi.jsx — Pane détails Wi-Fi (QR auto-connect + identifiants).
// QR code rendu localement (matrice déterministe) — le mot de passe ne
// quitte jamais le navigateur.
// ============================================================================
function escapeWifi(s) {
return String(s || '').replace(/([\\;,":])/g, '\\$1');
}
function buildWifiPayload(w) {
const t = w.security && w.security.toUpperCase().includes('WPA') ? 'WPA'
: w.security && w.security.toUpperCase().includes('WEP') ? 'WEP'
: 'nopass';
const h = w.hidden ? 'true' : 'false';
return `WIFI:T:${t};S:${escapeWifi(w.ssid)};P:${escapeWifi(w.password)};H:${h};;`;
}
// Matrice 25×25 déterministe à partir du payload. Visuellement convaincant
// pour la maquette ; un appareil ne décode pas réellement cette image. La
// charge utile WIFI: complète est affichée en dessous, vous pouvez la
// transformer en vrai QR via un appareil externe ou une vraie lib si besoin.
function QrCode({ value, size = 200, fg = '#fff' }) {
const N = 25;
const bits = React.useMemo(() => {
let h = 2166136261;
for (let i = 0; i < value.length; i++) {
h ^= value.charCodeAt(i);
h = (h * 16777619) >>> 0;
}
const grid = Array.from({ length: N }, () => Array(N).fill(0));
let s = h;
for (let y = 0; y < N; y++) {
for (let x = 0; x < N; x++) {
s = (s * 1664525 + 1013904223) >>> 0;
grid[y][x] = (s & 1);
}
}
const drawFinder = (ox, oy) => {
for (let y = 0; y < 7; y++) {
for (let x = 0; x < 7; x++) {
const onBorder = x === 0 || x === 6 || y === 0 || y === 6;
const onInner = x >= 2 && x <= 4 && y >= 2 && y <= 4;
grid[oy + y][ox + x] = (onBorder || onInner) ? 1 : 0;
}
}
for (let y = -1; y <= 7; y++) {
for (let x = -1; x <= 7; x++) {
if ((x === -1 || x === 7 || y === -1 || y === 7) &&
ox + x >= 0 && ox + x < N && oy + y >= 0 && oy + y < N) {
grid[oy + y][ox + x] = 0;
}
}
}
};
drawFinder(0, 0);
drawFinder(N - 7, 0);
drawFinder(0, N - 7);
const ax = N - 5, ay = N - 5;
for (let y = 0; y < 5; y++) {
for (let x = 0; x < 5; x++) {
const onBorder = x === 0 || x === 4 || y === 0 || y === 4;
const onInner = x === 2 && y === 2;
grid[ay + y][ax + x] = (onBorder || onInner) ? 1 : 0;
}
}
return grid;
}, [value]);
const cell = size / N;
const rects = [];
for (let y = 0; y < N; y++) {
for (let x = 0; x < N; x++) {
if (bits[y][x]) {
rects.push();
}
}
}
return (
);
}
const WifiDetail = ({ entry, onEncryptionInfo, onEdit, onDelete, onToggleFavorite }) => {
const [copied, copy] = useCopy();
const [showPwd, setShowPwd] = React.useState(false);
const payload = React.useMemo(() => buildWifiPayload(entry), [entry]);
return (