rtc_prd/wifi-config.html
2026-02-04 15:33:02 +08:00

502 lines
17 KiB
HTML

<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover">
<title>Airhub - WiFi配网</title>
<link rel="stylesheet" href="styles.css">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link
href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&family=Press+Start+2P&display=swap"
rel="stylesheet">
<style>
/* WiFi Config specific styles */
.wifi-steps {
display: flex;
justify-content: center;
gap: 8px;
margin-bottom: 32px;
}
.step-dot {
width: 8px;
height: 8px;
border-radius: 50%;
background: rgba(167, 139, 250, 0.3);
transition: all 0.3s ease;
}
.step-dot.active {
background: #8B5CF6;
width: 24px;
border-radius: 4px;
}
.step-dot.completed {
background: #22C55E;
}
.wifi-icon {
width: 80px;
height: 80px;
margin-bottom: 24px;
}
.wifi-list {
width: 100%;
max-width: 320px;
display: flex;
flex-direction: column;
gap: 12px;
}
.wifi-item {
display: flex;
align-items: center;
padding: 16px;
background: rgba(255, 255, 255, 0.8);
backdrop-filter: blur(10px);
border-radius: 16px;
border: 1px solid rgba(255, 255, 255, 0.5);
cursor: pointer;
transition: all 0.2s ease;
}
.wifi-item:hover {
background: rgba(255, 255, 255, 0.95);
transform: translateY(-2px);
}
.wifi-item.selected {
border-color: #8B5CF6;
box-shadow: 0 0 0 2px rgba(139, 92, 246, 0.2);
}
.wifi-name {
flex: 1;
font-weight: 500;
color: #1F2937;
}
.wifi-signal {
color: #6B7280;
font-size: 20px;
}
.password-input {
width: 100%;
max-width: 320px;
padding: 16px 20px;
border: 1px solid rgba(255, 255, 255, 0.5);
background: rgba(255, 255, 255, 0.8);
backdrop-filter: blur(10px);
border-radius: 16px;
font-size: 16px;
font-family: inherit;
outline: none;
transition: all 0.2s ease;
}
.password-input:focus {
border-color: #8B5CF6;
box-shadow: 0 0 0 3px rgba(139, 92, 246, 0.15);
}
.progress-container {
width: 100%;
max-width: 280px;
text-align: center;
}
.progress-bar {
height: 6px;
background: rgba(139, 92, 246, 0.2);
border-radius: 3px;
overflow: hidden;
margin-bottom: 16px;
}
.progress-fill {
height: 100%;
background: linear-gradient(90deg, #22D3EE, #8B5CF6);
border-radius: 3px;
width: 0%;
transition: width 0.3s ease;
}
.progress-text {
color: #6B7280;
font-size: 14px;
}
.result-icon {
font-size: 64px;
margin-bottom: 16px;
}
.result-title {
font-size: 24px;
font-weight: 600;
color: #1F2937;
margin-bottom: 8px;
}
.result-desc {
color: #6B7280;
font-size: 14px;
}
.step-content {
display: none;
flex-direction: column;
align-items: center;
width: 100%;
}
.step-content.active {
display: flex;
}
</style>
</head>
<body>
<!-- Animated Background -->
<div class="gradient-bg">
<div class="gradient-layer layer-1"></div>
<div class="gradient-layer layer-2"></div>
<div class="gradient-layer layer-3"></div>
</div>
<div class="page bluetooth-page active">
<header class="bt-header">
<button class="back-btn" onclick="goBack()">
<svg width="24" height="24" viewBox="0 0 24 24" fill="none">
<path d="M15 18L9 12L15 6" stroke="currentColor" stroke-width="2" stroke-linecap="round"
stroke-linejoin="round" />
</svg>
</button>
<h1 class="bt-title">WiFi配网</h1>
<div class="header-spacer"></div>
</header>
<main class="bt-content">
<!-- Step indicators -->
<div class="wifi-steps">
<div class="step-dot active" id="dot1"></div>
<div class="step-dot" id="dot2"></div>
<div class="step-dot" id="dot3"></div>
<div class="step-dot" id="dot4"></div>
</div>
<!-- Step 1: Select Network -->
<div class="step-content active" id="step1">
<svg class="wifi-icon" viewBox="0 0 24 24" fill="none">
<path d="M5 12.55a11 11 0 0 1 14.08 0" stroke="#8B5CF6" stroke-width="2" stroke-linecap="round" />
<path d="M1.42 9a16 16 0 0 1 21.16 0" stroke="#8B5CF6" stroke-width="2" stroke-linecap="round" />
<path d="M8.53 16.11a6 6 0 0 1 6.95 0" stroke="#8B5CF6" stroke-width="2" stroke-linecap="round" />
<circle cx="12" cy="20" r="1" fill="#8B5CF6" />
</svg>
<h2 style="margin-bottom: 8px; color: #1F2937;">选择WiFi网络</h2>
<p style="color: #6B7280; margin-bottom: 24px;">设备需要连接WiFi以使用AI功能</p>
<div class="wifi-list" id="wifiList">
<div class="wifi-item" onclick="selectWifi(this, 'Home_5G')">
<span class="wifi-name">Home_5G</span>
<img src="icons/wifi-4.svg" class="wifi-level-icon" alt="Strong">
</div>
<div class="wifi-item" onclick="selectWifi(this, 'Office_WiFi')">
<span class="wifi-name">Office_WiFi</span>
<img src="icons/wifi-3.svg" class="wifi-level-icon" alt="Good">
</div>
<div class="wifi-item" onclick="selectWifi(this, 'Guest_Network')">
<span class="wifi-name">Guest_Network</span>
<img src="icons/wifi-2.svg" class="wifi-level-icon" alt="Weak">
</div>
</div>
</div>
<!-- Step 2: Enter Password -->
<div class="step-content" id="step2">
<svg class="wifi-icon" viewBox="0 0 24 24" fill="none">
<rect x="3" y="11" width="18" height="11" rx="2" stroke="#8B5CF6" stroke-width="2" />
<circle cx="12" cy="16" r="1" fill="#8B5CF6" />
<path d="M7 11V7a5 5 0 0110 0v4" stroke="#8B5CF6" stroke-width="2" />
</svg>
<h2 style="margin-bottom: 8px; color: #1F2937;" id="selectedWifiName">网络名称</h2>
<p style="color: #6B7280; margin-bottom: 24px;">请输入WiFi密码</p>
<input type="password" class="password-input" id="wifiPassword" placeholder="输入密码">
</div>
<!-- Step 3: Connecting -->
<div class="step-content" id="step3">
<svg class="wifi-icon connecting-anim" viewBox="0 0 24 24" fill="none">
<path class="wifi-wave wave-3" d="M5 12.55a11 11 0 0 1 14.08 0" stroke="#8B5CF6" stroke-width="2"
stroke-linecap="round" />
<path class="wifi-wave wave-2" d="M1.42 9a16 16 0 0 1 21.16 0" stroke="#8B5CF6" stroke-width="2"
stroke-linecap="round" />
<path class="wifi-wave wave-1" d="M8.53 16.11a6 6 0 0 1 6.95 0" stroke="#8B5CF6" stroke-width="2"
stroke-linecap="round" />
<circle class="wifi-dot" cx="12" cy="20" r="1" fill="#8B5CF6" />
</svg>
<h2 style="margin-bottom: 24px; color: #1F2937;">正在配网...</h2>
<div class="progress-container">
<div class="progress-bar">
<div class="progress-fill" id="progressFill"></div>
</div>
<p class="progress-text" id="progressText">正在连接WiFi...</p>
</div>
</div>
<!-- Step 4: Result -->
<div class="step-content" id="step4">
<!-- Dynamic Device Icon Container -->
<div class="success-icon-wrapper">
<img src="" alt="Device" id="successDeviceImg" class="success-device-img">
<div class="success-badge"></div>
</div>
<h2 class="result-title" id="resultTitle">配网成功!</h2>
<p class="result-desc" id="resultDesc">设备已成功连接到网络</p>
</div>
</main>
<footer class="bt-footer">
<button class="cancel-btn" id="cancelBtn" onclick="goBack()">取消</button>
<button class="connect-device-btn" id="nextBtn" onclick="nextStep()" style="display: none;">
<span class="btn-text" id="nextBtnText">下一步</span>
</button>
</footer>
</div>
<style>
.wifi-level-icon {
width: 24px;
height: 24px;
opacity: 0.8;
}
/* Connecting Animation */
.connecting-anim .wifi-wave {
stroke-opacity: 0.3;
animation: wifiPulse 1.5s infinite ease-in-out;
}
.connecting-anim .wave-1 {
animation-delay: 0.0s;
}
.connecting-anim .wave-2 {
animation-delay: 0.5s;
}
.connecting-anim .wave-3 {
animation-delay: 1.0s;
}
/* Outer wave */
@keyframes wifiPulse {
0%,
100% {
stroke-opacity: 0.3;
stroke: #8B5CF6;
}
50% {
stroke-opacity: 1;
stroke: #8B5CF6;
}
}
/* Success Icon Styles */
.success-icon-wrapper {
position: relative;
width: 120px;
height: 120px;
display: flex;
align-items: center;
justify-content: center;
margin-bottom: 24px;
}
.success-device-img {
width: 120px;
height: 120px;
image-rendering: pixelated;
filter: drop-shadow(0 10px 20px rgba(139, 92, 246, 0.2));
animation: floatSuccess 3s ease-in-out infinite;
}
.success-badge {
position: absolute;
bottom: -5px;
right: -5px;
width: 32px;
height: 32px;
background: #22C55E;
color: white;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
font-size: 18px;
border: 3px solid white;
box-shadow: 0 4px 10px rgba(34, 197, 94, 0.3);
animation: popIn 0.5s cubic-bezier(0.175, 0.885, 0.32, 1.275) forwards;
}
@keyframes floatSuccess {
0%,
100% {
transform: translateY(0);
}
50% {
transform: translateY(-10px);
}
}
@keyframes popIn {
from {
transform: scale(0);
}
to {
transform: scale(1);
}
}
</style>
<script>
let currentStep = 1;
let selectedWifi = '';
// Load device info immediately
let currentDevice = {};
try {
currentDevice = JSON.parse(localStorage.getItem('lastActiveDevice') || '{}');
console.log("Loaded device:", currentDevice);
} catch (e) { console.error(e); }
function getDeviceIcon(type) {
// Normalize type keys to match bluetooth.html
// Mappings: 'plush' -> capybara, 'badge_ai' -> badge-ai, 'badge' -> badge-basic
if (type === 'plush_core' || type === 'plush') return 'icons/pixel-capybara.svg';
if (type === 'badge_ai') return 'icons/pixel-badge-ai.svg';
if (type === 'badge_basic' || type === 'badge') return 'icons/pixel-badge-basic.svg';
return 'icons/pixel-badge-basic.svg'; // Fallback
}
function selectWifi(element, name) {
document.querySelectorAll('.wifi-item').forEach(el => el.classList.remove('selected'));
element.classList.add('selected');
selectedWifi = name;
document.getElementById('nextBtn').style.display = 'flex';
}
function nextStep() {
if (currentStep === 1 && !selectedWifi) return;
if (currentStep === 2 && !document.getElementById('wifiPassword').value) return;
currentStep++;
updateStepUI();
if (currentStep === 2) {
document.getElementById('selectedWifiName').textContent = selectedWifi;
}
if (currentStep === 3) {
startConnecting();
}
if (currentStep === 4) {
// Show device icon
const img = document.getElementById('successDeviceImg');
img.src = getDeviceIcon(currentDevice.type || 'badge_basic');
document.getElementById('nextBtnText').textContent = '进入设备';
document.getElementById('cancelBtn').style.display = 'none';
}
}
function updateStepUI() {
// Update step dots
for (let i = 1; i <= 4; i++) {
const dot = document.getElementById('dot' + i);
dot.classList.remove('active', 'completed');
if (i < currentStep) dot.classList.add('completed');
if (i === currentStep) dot.classList.add('active');
}
// Update step content
for (let i = 1; i <= 4; i++) {
const step = document.getElementById('step' + i);
step.classList.remove('active');
if (i === currentStep) step.classList.add('active');
}
// Update button text
if (currentStep === 2) {
document.getElementById('nextBtnText').textContent = '连接';
}
}
function startConnecting() {
document.getElementById('nextBtn').style.display = 'none';
const progressFill = document.getElementById('progressFill');
const progressText = document.getElementById('progressText');
const steps = [
{ progress: 30, text: '正在连接WiFi...' },
{ progress: 60, text: '正在验证密码...' },
{ progress: 90, text: '正在同步设备...' },
{ progress: 100, text: '完成!' }
];
let stepIndex = 0;
const interval = setInterval(() => {
if (stepIndex < steps.length) {
progressFill.style.width = steps[stepIndex].progress + '%';
progressText.textContent = steps[stepIndex].text;
stepIndex++;
} else {
clearInterval(interval);
setTimeout(() => {
currentStep = 4;
// Use button-triggered transition or auto
updateStepUI();
// Setup final state manually here as well to be safe
const img = document.getElementById('successDeviceImg');
if (img) img.src = getDeviceIcon(currentDevice.type || 'badge_basic');
document.getElementById('nextBtn').style.display = 'flex';
document.getElementById('nextBtnText').textContent = '进入设备';
document.getElementById('cancelBtn').style.display = 'none';
document.getElementById('nextBtn').onclick = () => {
window.location.href = 'device-control.html?t=' + new Date().getTime();
};
}, 500);
}
}, 800);
}
function goBack() {
if (currentStep > 1) {
currentStep--;
updateStepUI();
if (currentStep === 1) {
document.getElementById('nextBtn').style.display = selectedWifi ? 'flex' : 'none';
document.getElementById('nextBtnText').textContent = '下一步';
}
} else {
window.location.href = 'bluetooth.html';
}
}
</script>
</body>
</html>