小程序初始化
This commit is contained in:
@@ -0,0 +1,151 @@
|
||||
import { state } from './state.js';
|
||||
import { UI } from './components.js';
|
||||
|
||||
export const Onboarding = {
|
||||
onComplete: null,
|
||||
|
||||
render(onCompleteCallback) {
|
||||
if (onCompleteCallback) this.onComplete = onCompleteCallback;
|
||||
|
||||
const container = document.getElementById('view-container');
|
||||
container.innerHTML = `
|
||||
<div id="onboarding-root" class="w-full h-full glass-card p-10 flex flex-col justify-between overflow-hidden relative">
|
||||
<div id="step-content" class="flex-1 flex flex-col justify-center max-w-2xl mx-auto w-full"></div>
|
||||
|
||||
<div class="flex items-center justify-between mt-10 max-w-2xl mx-auto w-full border-t border-white/5 pt-8">
|
||||
<div id="step-indicator" class="flex gap-2">
|
||||
${[1,2,3,4,5].map(i => `<div class="step-dot-${i} w-3 h-1 rounded-full bg-white/10 transition-all duration-500"></div>`).join('')}
|
||||
</div>
|
||||
<div class="flex gap-4">
|
||||
<button id="prev-step" class="hidden text-white/40 px-6 py-2 text-sm hover:text-white transition-colors">返回</button>
|
||||
<button id="next-step" class="glass-btn px-8 py-3 rounded-full text-orange-200 font-bold tracking-widest text-sm shadow-xl shadow-orange-900/10">
|
||||
下一章 <i data-lucide="arrow-right" class="w-4 h-4 ml-2"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
this.renderStep(state.currentStep || 1);
|
||||
this.initEvents();
|
||||
},
|
||||
|
||||
renderStep(step) {
|
||||
const content = document.getElementById('step-content');
|
||||
const nextBtn = document.getElementById('next-step');
|
||||
const prevBtn = document.getElementById('prev-step');
|
||||
|
||||
|
||||
for(let i=1; i<=5; i++){
|
||||
const dot = document.querySelector(`.step-dot-${i}`);
|
||||
if(dot) dot.className = `step-dot-${i} h-1 rounded-full transition-all duration-500 ${i === step ? 'w-8 bg-orange-200' : 'w-3 bg-white/10'}`;
|
||||
}
|
||||
|
||||
prevBtn.classList.toggle('hidden', step === 1);
|
||||
nextBtn.innerHTML = step === 5 ? '开启人生 <i data-lucide="check" class="w-4 h-4 ml-2"></i>' : '继续 <i data-lucide="arrow-right" class="w-4 h-4 ml-2"></i>';
|
||||
|
||||
let html = '';
|
||||
if (step === 1) {
|
||||
html = `
|
||||
<div class="animate-fade-in space-y-8">
|
||||
<div class="mb-6">
|
||||
<h2 class="text-4xl font-serif mb-3">你是谁?</h2>
|
||||
<p class="text-white/40 italic text-sm">定义你生命坐标的初始属性。</p>
|
||||
</div>
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-x-6 gap-y-2">
|
||||
${UI.renderInput('称呼', 'reg-nickname', 'text', '例如:林中鹿', state.registrationData.nickname)}
|
||||
${UI.renderInput('性别', 'reg-gender', 'text', '自由填写', state.registrationData.gender)}
|
||||
${UI.renderInput('MBTI', 'reg-mbti', 'text', '如:INFJ', state.registrationData.mbti)}
|
||||
${UI.renderInput('星座', 'reg-zodiac', 'text', '星辰指引', state.registrationData.zodiac)}
|
||||
</div>
|
||||
${UI.renderInput('兴趣爱好', 'reg-hobbies', 'text', '用逗号分隔你的热爱', (state.registrationData.hobbies || []).join(','))}
|
||||
</div>
|
||||
`;
|
||||
} else if (step === 2) {
|
||||
html = this.renderMemoryStep('那段纯真的时光', '童年记忆', 'reg-child-text', 'reg-child-date', 'childhood', state.registrationData.childhood);
|
||||
} else if (step === 3) {
|
||||
html = this.renderMemoryStep('光芒闪耀的时刻', '开心的经历', 'reg-joy-text', 'reg-joy-date', 'joy', state.registrationData.joy);
|
||||
} else if (step === 4) {
|
||||
html = this.renderMemoryStep('在暗夜中潜行', '沮丧与低谷', 'reg-low-text', 'reg-low-date', 'low', state.registrationData.low);
|
||||
} else if (step === 5) {
|
||||
html = `
|
||||
<div class="animate-fade-in space-y-8">
|
||||
<div class="mb-6">
|
||||
<h2 class="text-4xl font-serif mb-3">未来想成为谁?</h2>
|
||||
<p class="text-white/40 italic text-sm">勾勒你对理想生活的全部向往。</p>
|
||||
</div>
|
||||
${UI.renderTextArea('对未来的憧憬', 'reg-future-vision', '你想成为一个什么样的人?', state.registrationData.future.vision || '')}
|
||||
${UI.renderTextArea('理想生活状态', 'reg-future-ideal', '你的理想清晨与傍晚是怎样的?', state.registrationData.future.ideal || '')}
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
content.innerHTML = html;
|
||||
lucide.createIcons();
|
||||
},
|
||||
|
||||
renderMemoryStep(title, label, textId, dateId, type, data) {
|
||||
return `
|
||||
<div class="animate-fade-in space-y-6">
|
||||
<div>
|
||||
<h2 class="text-4xl font-serif mb-3">${title}</h2>
|
||||
<p class="text-white/40 italic text-sm">回望足迹,这些瞬间如何塑造了此时的你。</p>
|
||||
</div>
|
||||
<div class="space-y-4">
|
||||
<div class="flex flex-col gap-2">
|
||||
<label class="text-[10px] text-white/30 uppercase tracking-widest font-bold">${label}的日期</label>
|
||||
<input type="date" id="${dateId}" value="${data.date || ''}" class="glass-input max-w-xs">
|
||||
</div>
|
||||
<div class="space-y-2">
|
||||
<label class="text-[10px] text-white/30 uppercase tracking-widest font-bold">详细描述</label>
|
||||
<textarea id="${textId}" rows="5" class="glass-input w-full text-sm" placeholder="描述那段时光发生的点滴...">${data.text || ''}</textarea>
|
||||
</div>
|
||||
<div class="flex flex-wrap gap-2 pt-2">
|
||||
${UI.renderInspiration(type, textId)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
},
|
||||
|
||||
saveStepData() {
|
||||
const step = state.currentStep;
|
||||
if (step === 1) {
|
||||
state.updateRegistration({
|
||||
nickname: document.getElementById('reg-nickname').value,
|
||||
gender: document.getElementById('reg-gender').value,
|
||||
mbti: document.getElementById('reg-mbti').value,
|
||||
zodiac: document.getElementById('reg-zodiac').value,
|
||||
hobbies: document.getElementById('reg-hobbies').value.split(',').map(s => s.trim()).filter(s => s)
|
||||
});
|
||||
} else if (step === 2) {
|
||||
state.updateRegistration({ childhood: { date: document.getElementById('reg-child-date').value, text: document.getElementById('reg-child-text').value } });
|
||||
} else if (step === 3) {
|
||||
state.updateRegistration({ joy: { date: document.getElementById('reg-joy-date').value, text: document.getElementById('reg-joy-text').value } });
|
||||
} else if (step === 4) {
|
||||
state.updateRegistration({ low: { date: document.getElementById('reg-low-date').value, text: document.getElementById('reg-low-text').value } });
|
||||
} else if (step === 5) {
|
||||
state.updateRegistration({
|
||||
future: { vision: document.getElementById('reg-future-vision').value, ideal: document.getElementById('reg-future-ideal').value }
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
initEvents() {
|
||||
document.getElementById('next-step').onclick = () => {
|
||||
this.saveStepData();
|
||||
if (state.currentStep < 5) {
|
||||
state.currentStep++;
|
||||
this.renderStep(state.currentStep);
|
||||
} else {
|
||||
state.view = 'dashboard';
|
||||
state.save();
|
||||
if (this.onComplete) this.onComplete();
|
||||
}
|
||||
};
|
||||
document.getElementById('prev-step').onclick = () => {
|
||||
if (state.currentStep > 1) {
|
||||
state.currentStep--;
|
||||
this.renderStep(state.currentStep);
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user