Fix medium priority issues from code review
- Add DEPLOY_TIMING constants for deployment simulation - Add null checks in switchTab function for consistency - Add role="radiogroup" and fieldset/legend to wizard steps - Add role="log" and aria-live="polite" to chat container - Add bottom border to active pricing region button for better visual distinction Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
19
app.js
19
app.js
@@ -58,6 +58,14 @@ const PAYMENT_METHODS = [
|
||||
{ id: 'yearly', name: '연간 결제', desc: '2개월 무료 (17% 할인)', discount: 17 }
|
||||
];
|
||||
|
||||
// 배포 시뮬레이션 타이밍 상수
|
||||
const DEPLOY_TIMING = {
|
||||
IMAGE_READY: 1500,
|
||||
CONTAINER_CREATED: 3000,
|
||||
NETWORK_CONFIGURED: 4500,
|
||||
COMPLETE: 6000
|
||||
};
|
||||
|
||||
/**
|
||||
* 가격 포맷팅 (한국 원화)
|
||||
*/
|
||||
@@ -197,26 +205,26 @@ function anvilApp() {
|
||||
this.logs.push('✅ 이미지 준비 완료');
|
||||
this.logs.push('🔧 컨테이너 인스턴스 생성 중...');
|
||||
this.deployStep = 2;
|
||||
}, 1500);
|
||||
}, DEPLOY_TIMING.IMAGE_READY);
|
||||
|
||||
setTimeout(() => {
|
||||
this.logs.push('✅ 컨테이너 생성 완료');
|
||||
this.logs.push('🌐 네트워크 및 방화벽 구성 중...');
|
||||
this.deployStep = 3;
|
||||
}, 3000);
|
||||
}, DEPLOY_TIMING.CONTAINER_CREATED);
|
||||
|
||||
setTimeout(() => {
|
||||
const randomIP = Math.floor(Math.random() * 254 + 1);
|
||||
this.logs.push(`✅ IP 할당 완료: 45.12.89.${randomIP}`);
|
||||
this.logs.push('⚙️ 시스템 서비스 시작 중...');
|
||||
this.deployStep = 4;
|
||||
}, 4500);
|
||||
}, DEPLOY_TIMING.NETWORK_CONFIGURED);
|
||||
|
||||
setTimeout(() => {
|
||||
this.launching = false;
|
||||
this.deployStep = 5;
|
||||
this.logs.push('🎉 서버가 활성화되었습니다!');
|
||||
}, 6000);
|
||||
}, DEPLOY_TIMING.COMPLETE);
|
||||
},
|
||||
|
||||
// 런처 열기
|
||||
@@ -275,6 +283,9 @@ function switchTab(tab) {
|
||||
const panelN8n = document.getElementById('panel-n8n');
|
||||
const panelTf = document.getElementById('panel-tf');
|
||||
|
||||
// Null checks for DOM elements
|
||||
if (!btnN8n || !btnTf || !panelN8n || !panelTf) return;
|
||||
|
||||
if (tab === 'n8n') {
|
||||
// Update ARIA states for n8n tab
|
||||
btnN8n.setAttribute('aria-selected', 'true');
|
||||
|
||||
23
index.html
23
index.html
@@ -551,11 +551,11 @@
|
||||
<!-- Tab Buttons -->
|
||||
<div class="flex justify-center mb-8">
|
||||
<div class="glass-panel p-1.5 rounded-2xl inline-flex gap-1">
|
||||
<button @click="region = 'global'" :class="region === 'global' ? 'bg-gradient-to-r from-brand-600 to-brand-500 text-white shadow-lg shadow-brand-500/30' : 'text-slate-400 hover:text-white hover:bg-white/5'" class="px-6 py-3 rounded-xl text-sm font-bold transition-all flex items-center gap-2">
|
||||
<button @click="region = 'global'" :class="region === 'global' ? 'bg-gradient-to-r from-brand-600 to-brand-500 text-white shadow-lg shadow-brand-500/30 border-b-2 border-b-white/60' : 'text-slate-400 hover:text-white hover:bg-white/5'" class="px-6 py-3 rounded-xl text-sm font-bold transition-all flex items-center gap-2">
|
||||
<span>🌏 Global</span>
|
||||
<span class="text-[10px] font-normal opacity-80">(Tokyo/SG/HK)</span>
|
||||
</button>
|
||||
<button @click="region = 'seoul'" :class="region === 'seoul' ? 'bg-gradient-to-r from-brand-600 to-brand-500 text-white shadow-lg shadow-brand-500/30' : 'text-slate-400 hover:text-white hover:bg-white/5'" class="px-6 py-3 rounded-xl text-sm font-bold transition-all flex items-center gap-2">
|
||||
<button @click="region = 'seoul'" :class="region === 'seoul' ? 'bg-gradient-to-r from-brand-600 to-brand-500 text-white shadow-lg shadow-brand-500/30 border-b-2 border-b-white/60' : 'text-slate-400 hover:text-white hover:bg-white/5'" class="px-6 py-3 rounded-xl text-sm font-bold transition-all flex items-center gap-2">
|
||||
<span>🇰🇷 Seoul</span>
|
||||
<span class="text-[10px] font-normal opacity-80">(Premium)</span>
|
||||
</button>
|
||||
@@ -774,7 +774,7 @@
|
||||
</div>
|
||||
|
||||
<!-- Chat Container -->
|
||||
<div id="chat-container" class="flex-1 overflow-y-auto px-3 sm:px-6 py-3 sm:py-4 space-y-2 sm:space-y-4" x-show="wizardStep < 5">
|
||||
<div id="chat-container" role="log" aria-live="polite" class="flex-1 overflow-y-auto px-3 sm:px-6 py-3 sm:py-4 space-y-2 sm:space-y-4" x-show="wizardStep < 5">
|
||||
<!-- Messages -->
|
||||
<template x-for="(msg, idx) in messages" :key="idx">
|
||||
<div :class="msg.type === 'bot' ? 'flex justify-start' : 'flex justify-end'"
|
||||
@@ -793,7 +793,7 @@
|
||||
<!-- Current Step Options -->
|
||||
<div class="pt-2">
|
||||
<!-- Step 0: Region Selection -->
|
||||
<fieldset x-show="wizardStep === 0" class="space-y-3">
|
||||
<fieldset x-show="wizardStep === 0" role="radiogroup" aria-label="리전 선택" class="space-y-3">
|
||||
<legend class="sr-only">리전 선택 (지역 선택)</legend>
|
||||
<template x-for="r in regions" :key="r.id">
|
||||
<button @click="selectRegion(r)"
|
||||
@@ -817,7 +817,8 @@
|
||||
</fieldset>
|
||||
|
||||
<!-- Step 1: Plan Selection -->
|
||||
<div x-show="wizardStep === 1" class="space-y-3">
|
||||
<fieldset x-show="wizardStep === 1" class="space-y-3">
|
||||
<legend class="sr-only">플랜 선택 (서버 사양 선택)</legend>
|
||||
<template x-for="p in plans" :key="p">
|
||||
<button @click="selectPlan(p)"
|
||||
class="w-full flex items-center justify-between px-5 py-4 bg-slate-800/80 hover:bg-slate-700 border border-slate-700/50 hover:border-brand-500/50 rounded-xl transition-all">
|
||||
@@ -835,10 +836,11 @@
|
||||
</div>
|
||||
</button>
|
||||
</template>
|
||||
</div>
|
||||
</fieldset>
|
||||
|
||||
<!-- Step 2: OS Selection -->
|
||||
<div x-show="wizardStep === 2" class="space-y-3">
|
||||
<fieldset x-show="wizardStep === 2" class="space-y-3">
|
||||
<legend class="sr-only">운영체제 선택</legend>
|
||||
<template x-for="os in osList" :key="os.id">
|
||||
<button @click="selectOS(os)"
|
||||
class="w-full flex items-center gap-4 px-5 py-4 bg-slate-800/80 hover:bg-slate-700 border border-slate-700/50 hover:border-purple-500/50 rounded-xl transition-all">
|
||||
@@ -846,10 +848,11 @@
|
||||
<span class="font-semibold text-white text-base" x-text="os.name"></span>
|
||||
</button>
|
||||
</template>
|
||||
</div>
|
||||
</fieldset>
|
||||
|
||||
<!-- Step 3: Payment Selection -->
|
||||
<div x-show="wizardStep === 3" class="space-y-3">
|
||||
<fieldset x-show="wizardStep === 3" class="space-y-3">
|
||||
<legend class="sr-only">결제 방식 선택</legend>
|
||||
<template x-for="pay in paymentMethods" :key="pay.id">
|
||||
<button @click="selectPayment(pay)"
|
||||
class="w-full flex items-center justify-between px-5 py-4 bg-slate-800/80 hover:bg-slate-700 border border-slate-700/50 hover:border-green-500/50 rounded-xl transition-all">
|
||||
@@ -862,7 +865,7 @@
|
||||
</div>
|
||||
</button>
|
||||
</template>
|
||||
</div>
|
||||
</fieldset>
|
||||
|
||||
<!-- Step 4: Confirmation -->
|
||||
<div x-show="wizardStep === 4" class="space-y-4">
|
||||
|
||||
Reference in New Issue
Block a user