document.addEventListener('DOMContentLoaded', () => { const LIFE_EVENTS_STORAGE_KEY = 'kaixinapp_life_events_v1'; let lifeEvents = []; let nextLifeEventId = 1; const addLifeEventBtn = document.getElementById('add-life-event-btn'); const lifeEventsTimelineContainer = document.getElementById('life-events-timeline'); const lifeEventsEmptyState = document.getElementById('life-events-empty'); const addEventModal = document.getElementById('add-event-modal'); const addEventModalContent = document.getElementById('add-event-modal-content'); const cancelAddEventBtn = document.getElementById('cancel-add-event'); const lifeEventForm = document.getElementById('life-event-form'); const writeLetterModal = document.getElementById('write-letter-modal'); const writeLetterModalContent = document.getElementById('write-letter-modal-content'); const closeLetterModalBtn = document.getElementById('close-letter-modal'); const letterEventTitle = document.getElementById('letter-event-title'); const letterPlaceholder = document.getElementById('letter-placeholder'); const letterFinalContent = document.getElementById('letter-final-content'); const regenerateLetterBtn = document.getElementById('regenerate-letter-btn'); const copyLetterBtn = document.getElementById('copy-letter-btn'); let activeLetterEventId = null; function loadLifeEvents() { const stored = localStorage.getItem(LIFE_EVENTS_STORAGE_KEY); if (stored) { lifeEvents = JSON.parse(stored); const maxId = lifeEvents.reduce((max, e) => Math.max(max, e.id), 0); nextLifeEventId = maxId + 1; } else { lifeEvents = [{ id: 1, date: '2024-06-15', title: '大学毕业典礼', content: '四年的大学生活画上了句号。穿着学士服,和朋友、老师们告别,心中充满了不舍和对未来的憧憬。这是一个时代的结束,也是一个新开始。', type: 'positive', aiAnalysis: { title: '你做得很棒!', response: '我好喜欢你记录下这段记忆。
你在这件事情里,展现了【坚持】、【自我支持】和【成长】。
别小看这一刻的你,它证明了:你,是可以做到的。', keywords: ['坚持', '成长', '新起点'], emotionTags: ['自豪', '憧憬', '不舍'] } }, { id: 2, date: '2023-03-20', title: '一次重要的面试失败', content: '为心仪的公司准备了很久,但最终还是失败了。感觉很失落,甚至开始怀疑自己的能力。花了几天时间才慢慢走出来。', type: 'negative', aiAnalysis: { title: '这段经历可能对你带来的影响…', response: '你提到当时很难过,也许是因为你在那时没有得到你真正渴望的回应。
从那以后,这段经历可能让你在类似场景里格外敏感——
这不是脆弱,而是你曾经努力保护自己留下的本能。

开开理解你,也想和你一起慢慢松开这段结。', keywords: ['挫折', '反思', '坚韧'], emotionTags: ['失落', '焦虑', '怀疑'] } }]; nextLifeEventId = 3; saveLifeEvents(); } } function saveLifeEvents() { localStorage.setItem(LIFE_EVENTS_STORAGE_KEY, JSON.stringify(lifeEvents)); } function renderLifeEvents() { if (!lifeEventsTimelineContainer) return; if (lifeEvents.length === 0) { lifeEventsEmptyState.classList.remove('hidden'); lifeEventsTimelineContainer.classList.add('hidden'); } else { lifeEventsEmptyState.classList.add('hidden'); lifeEventsTimelineContainer.classList.remove('hidden'); lifeEvents.sort((a, b) => new Date(b.date) - new Date(a.date)); lifeEventsTimelineContainer.innerHTML = lifeEvents.map((event, index) => { const isLastItem = index === lifeEvents.length - 1; const cardBg = event.type === 'positive' ? 'bg-emerald-500/5 border-emerald-500/20' : 'bg-red-500/5 border-red-500/20'; const accentColor = event.type === 'positive' ? 'text-emerald-600' : 'text-red-600'; const icon = event.type === 'positive' ? 'sparkles' : 'heart-crack'; return `

${new Date(event.date).getFullYear()}

${new Date(event.date).toLocaleDateString('zh-CN', { month: '2-digit', day: '2-digit' }).replace('/', '-')}

${!isLastItem ? '
' : ''}

${event.title}

${event.content}

${event.aiAnalysis.title}

${event.aiAnalysis.response}
成长关键词:
${event.aiAnalysis.keywords.map(k => `${k}`).join('')}
情绪标签:
${event.aiAnalysis.emotionTags.map(t => `${t}`).join('')}
`; }).join(''); if (typeof lucide !== 'undefined') lucide.createIcons(); attachLifeEventButtonListeners(); } } function attachLifeEventButtonListeners() { document.querySelectorAll('[data-letter-event-id]').forEach(btn => { btn.addEventListener('click', () => { const eventId = btn.dataset.letterEventId; openWriteLetterModal(eventId); }); }); } function openModalAnimation(modal, content) { modal.classList.remove('hidden'); modal.classList.add('flex'); setTimeout(() => { modal.classList.remove('opacity-0'); content.classList.remove('scale-95', 'opacity-0'); }, 10); } function closeModalAnimation(modal, content) { modal.classList.add('opacity-0'); content.classList.add('scale-95', 'opacity-0'); setTimeout(() => { modal.classList.add('hidden'); modal.classList.remove('flex'); }, 300); } function showAddEventModal() { lifeEventForm.reset(); document.getElementById('event-date').value = new Date().toISOString().split('T')[0]; openModalAnimation(addEventModal, addEventModalContent); } function hideAddEventModal() { closeModalAnimation(addEventModal, addEventModalContent); } function handleLifeEventFormSubmit(e) { e.preventDefault(); const formData = new FormData(e.target); const event = { id: nextLifeEventId++, date: formData.get('date'), title: formData.get('title'), content: formData.get('content'), type: formData.get('eventType'), aiAnalysis: generateAiAnalysis(formData.get('content'), formData.get('eventType')) }; lifeEvents.push(event); saveLifeEvents(); renderLifeEvents(); hideAddEventModal(); } function generateAiAnalysis(content, type) { const analysis = {}; if (type === 'positive') { analysis.title = '你做得很棒!'; analysis.response = '我好喜欢你记录下这段记忆。
你在这件事情里,展现了【坚持】、【自我支持】和【成长】。
别小看这一刻的你,它证明了:你,是可以做到的。'; analysis.keywords = ['坚持', '自我支持', '成长']; analysis.emotionTags = ['快乐', '成就感', '自豪']; } else { analysis.title = '这段经历可能对你带来的影响…'; analysis.response = '你提到当时很难过,也许是因为你在那时没有得到你真正渴望的回应。
从那以后,这段经历可能让你在类似场景里格外敏感——
这不是脆弱,而是你曾经努力保护自己留下的本能。

开开理解你,也想和你一起慢慢松开这段结。'; analysis.keywords = ['反思', '坚韧', '接纳']; analysis.emotionTags = ['悲伤', '脆弱', '思考']; } if (content.includes('旅行')) analysis.keywords.push('探索'); if (content.includes('工作') || content.includes('面试')) analysis.keywords.push('职业'); if (content.includes('学习') || content.includes('毕业')) analysis.keywords.push('学业'); return analysis; } function openWriteLetterModal(eventId) { const event = lifeEvents.find(e => e.id == eventId); if (!event) return; activeLetterEventId = eventId; letterEventTitle.textContent = event.title; letterPlaceholder.style.display = 'block'; letterFinalContent.classList.add('hidden'); letterFinalContent.innerHTML = ''; openModalAnimation(writeLetterModal, writeLetterModalContent); generateLetter(event); } function hideWriteLetterModal() { closeModalAnimation(writeLetterModal, writeLetterModalContent); } function generateLetter(event) { letterPlaceholder.style.display = 'block'; letterFinalContent.classList.add('hidden'); setTimeout(() => { let letter; if (event.type === 'positive') { letter = `

亲爱的,在【${event.date}】的你:

你好呀!我是来自未来的你,特地让开开捎来这封信。

我知道,在【${event.title}】的那一刻,你的心里一定充满了阳光。你所感受到的那种【${event.aiAnalysis.emotionTags.join('、')}】的情绪,是那么真实和宝贵。请一定好好珍藏这份感觉。

你当时展现出的【${event.aiAnalysis.keywords.join('、')}】的品质,在未来的日子里,也一直闪闪发光,帮助我走了很远的路。谢谢你,当时的你,那么勇敢,那么棒。

请继续带着这份光芒走下去吧!未来可期!


爱你的,
未来的自己

`; } else { letter = `

亲爱的,在【${event.date}】的你:

你好。当你读到这封信时,我知道你正在经历【${event.title}】的艰难时刻,心里可能充满了【${event.aiAnalysis.emotionTags.join('、')}】的复杂感受。

我想告诉你,没关系,一切都会过去的。你当时的感受是完全正常的,请允许自己悲伤和脆弱。这不是你的错。这段经历虽然痛苦,但它也让你学会了【${event.aiAnalysis.keywords.join('、')}】。你比自己想象的要坚强得多。

请相信,未来的你,也就是我,已经从这段经历中走了出来,并且变得更加完整和强大。所以,请抱抱自己,告诉自己你已经做得很好了。


永远支持你的,
未来的自己

`; } letterFinalContent.innerHTML = letter; letterPlaceholder.style.display = 'none'; letterFinalContent.classList.remove('hidden'); }, 1500); } function handleCopyLetter() { const content = letterFinalContent.innerText; navigator.clipboard.writeText(content).then(() => { const copyButton = document.getElementById('copy-letter-btn'); const originalText = copyButton.innerHTML; copyButton.innerHTML = ` 已复制!`; if (typeof lucide !== 'undefined') lucide.createIcons(); setTimeout(() => { copyButton.innerHTML = originalText; if (typeof lucide !== 'undefined') lucide.createIcons(); }, 2000); }).catch(err => { console.error('Failed to copy: ', err); alert('复制失败'); }); } if(addLifeEventBtn) { addLifeEventBtn.addEventListener('click', showAddEventModal); cancelAddEventBtn.addEventListener('click', hideAddEventModal); addEventModal.addEventListener('click', (e) => { if (e.target === addEventModal) hideAddEventModal(); }); lifeEventForm.addEventListener('submit', handleLifeEventFormSubmit); closeLetterModalBtn.addEventListener('click', hideWriteLetterModal); writeLetterModal.addEventListener('click', (e) => { if (e.target === writeLetterModal) hideWriteLetterModal(); }); regenerateLetterBtn.addEventListener('click', () => { const event = lifeEvents.find(e => e.id == activeLetterEventId); if(event) generateLetter(event); }); copyLetterBtn.addEventListener('click', handleCopyLetter); loadLifeEvents(); renderLifeEvents(); } if (typeof lucide !== 'undefined') { lucide.createIcons(); } });