315 lines
13 KiB
Vue
315 lines
13 KiB
Vue
<template>
|
||
<div class="life-trajectory-page">
|
||
<!-- Header -->
|
||
<header id="main-header" class="fixed top-0 left-0 right-0 z-40 bg-white/80 backdrop-blur-lg transition-all duration-300">
|
||
<div class="container mx-auto px-6 py-4 flex justify-between items-center">
|
||
<router-link to="/" class="flex items-center space-x-2">
|
||
<svg width="32" height="32" viewBox="0 0 100 100" class="text-tech-blue">
|
||
<path fill="currentColor" d="M85.4,37.3C85.4,37.3,85.4,37.3,85.4,37.3c-2.8-9.9-10-17.7-19.1-21.2c-0.2-0.1-0.5-0.1-0.7-0.2c-0.1,0-0.2-0.1-0.3-0.1 c-1.2-0.4-2.5-0.8-3.7-1.1c-1-0.2-2-0.4-3-0.6c-1.1-0.2-2.1-0.3-3.2-0.4c-1.2-0.1-2.4-0.2-3.6-0.2c-0.1,0-0.2,0-0.3,0h-0.1 c-0.1,0-0.2,0-0.3,0c-1.2,0-2.4,0.1-3.6,0.2c-1.1,0.1-2.1,0.2-3.2,0.4c-1,0.2-2,0.4-3,0.6c-1.3,0.3-2.5,0.6-3.7,1.1 c-0.1,0-0.2,0.1-0.3,0.1c-0.2,0.1-0.5,0.1-0.7,0.2C21.6,19.6,14.4,27.4,11.6,37.3c0,0,0,0.1-0.1,0.1C8,47.7,8,58.8,11.5,69.2 c0,0.1,0.1,0.1,0.1,0.2c2.8,9.9,10,17.7,19.1,21.2c0.2,0.1,0.5,0.1,0.7,0.2c0.1,0,0.2,0.1,0.3,0.1c1.2,0.4,2.5,0.8,3.7,1.1 c1,0.2,2,0.4,3,0.6c1.1,0.2,2.1,0.3,3.2,0.4c1.2,0.1,2.4,0.2,3.6,0.2c0.1,0,0.2,0,0.3,0h0.1c0.1,0,0.2,0,0.3,0 c1.2,0,2.4-0.1,3.6-0.2c-1.1-0.1-2.1-0.2-3.2-0.4c1-0.2,2-0.4,3-0.6c1.3-0.3,2.5-0.6,3.7-1.1c0.1,0,0.2-0.1,0.3-0.1 c0.2-0.1,0.5-0.1,0.7-0.2c9.1-3.5,16.3-11.3,19.1-21.2c0-0.1,0.1-0.1,0.1-0.2C89,58.8,89,47.7,85.4,37.3z M50,77.9 c-15.4,0-27.9-12.5-27.9-27.9S34.6,22.1,50,22.1s27.9,12.5,27.9,27.9S65.4,77.9,50,77.9z"></path>
|
||
<path fill="var(--warm-orange)" d="M50,88.8c-21.4,0-38.8-17.4-38.8-38.8S28.6,11.2,50,11.2s38.8,17.4,38.8,38.8S71.4,88.8,50,88.8z M50,16.2 c-18.7,0-33.8,15.1-33.8,33.8S31.3,83.8,50,83.8s33.8-15.1,33.8-33.8S68.7,16.2,50,16.2z"></path>
|
||
</svg>
|
||
<span class="text-2xl font-bold text-tech-blue">开心APP</span>
|
||
</router-link>
|
||
<nav class="hidden lg:flex items-center space-x-8" id="nav-menu">
|
||
</nav>
|
||
<div class="flex items-center space-x-4">
|
||
<router-link to="/settings" class="hidden sm:inline-block text-text-medium hover:text-tech-blue transition-colors">登录</router-link>
|
||
<router-link to="/chat" class="bg-tech-blue text-white px-5 py-2.5 rounded-full font-semibold hover:bg-blue-600 transition-all duration-300 transform hover:scale-105 shadow-lg shadow-blue-500/20">免费开始</router-link>
|
||
<button
|
||
@click="toggleMobileMenu"
|
||
class="lg:hidden text-text-dark"
|
||
>
|
||
<i data-lucide="menu" class="w-6 h-6"></i>
|
||
</button>
|
||
</div>
|
||
</div>
|
||
</header>
|
||
|
||
<div
|
||
id="mobile-menu"
|
||
class="hidden fixed inset-0 bg-white/90 backdrop-blur-xl z-30 p-8 lg:hidden"
|
||
:class="{ 'hidden': !mobileMenuOpen }"
|
||
>
|
||
<nav class="flex flex-col space-y-6 text-center mt-16" id="mobile-nav-menu">
|
||
</nav>
|
||
</div>
|
||
|
||
<main class="pt-24 lg:pt-32 bg-light-gray pb-20">
|
||
<div class="container mx-auto px-6">
|
||
<header class="flex flex-col sm:flex-row justify-between items-start sm:items-center mb-10 animate-fade-in-up" style="animation-delay: 0.1s;">
|
||
<div class="mb-4 sm:mb-0">
|
||
<h1 class="text-4xl md:text-5xl font-bold text-text-dark flex items-center gap-3">
|
||
<i data-lucide="map-pin" class="w-10 h-10 text-warm-orange"></i>
|
||
人生轨迹
|
||
</h1>
|
||
<p class="text-lg text-text-medium mt-4">记录你的每一个重要时刻,见证成长</p>
|
||
</div>
|
||
<button
|
||
@click="showAddEventModal"
|
||
class="bg-warm-orange text-white px-6 py-3 rounded-full font-semibold hover:bg-orange-600 transition-all duration-300 transform hover:scale-105 shadow-lg shadow-orange-500/30 flex items-center space-x-2 animate-fade-in-up"
|
||
style="animation-delay: 0.3s;"
|
||
>
|
||
<i data-lucide="plus-circle" class="w-5 h-5"></i>
|
||
<span>添加人生事件</span>
|
||
</button>
|
||
</header>
|
||
|
||
<div id="life-events-timeline-container" class="animate-fade-in-up" style="animation-delay: 0.5s;">
|
||
<div
|
||
id="life-events-empty"
|
||
class="text-center py-20 border-2 border-dashed border-gray-300 rounded-2xl"
|
||
:class="{ 'hidden': lifeEvents.length > 0 }"
|
||
>
|
||
<i data-lucide="flag" class="w-16 h-16 mx-auto text-gray-400 mb-4"></i>
|
||
<p class="text-text-medium text-lg">你可以添加一件重要的事——不论它是美好还是悲伤,都值得被记录。</p>
|
||
</div>
|
||
<div id="life-events-timeline" class="space-y-12">
|
||
<!-- 示例人生事件 -->
|
||
<div class="bg-white p-6 rounded-xl shadow-lg border border-gray-200/50">
|
||
<div class="flex items-start space-x-4">
|
||
<div class="flex-shrink-0">
|
||
<div class="w-12 h-12 bg-emerald-100 rounded-full flex items-center justify-center">
|
||
<i data-lucide="graduation-cap" class="w-6 h-6 text-emerald-600"></i>
|
||
</div>
|
||
</div>
|
||
<div class="flex-1">
|
||
<div class="flex items-center justify-between mb-2">
|
||
<h3 class="text-xl font-bold text-text-dark">大学毕业</h3>
|
||
<span class="text-sm text-text-medium">2023年6月</span>
|
||
</div>
|
||
<p class="text-text-medium mb-4">
|
||
经过四年的努力,终于完成了大学学业。这是一个重要的里程碑,标志着学生时代的结束和新生活的开始。
|
||
</p>
|
||
<div class="flex items-center space-x-4">
|
||
<button
|
||
@click="writeLetter"
|
||
class="text-tech-blue hover:text-blue-600 font-medium text-sm flex items-center space-x-1"
|
||
>
|
||
<i data-lucide="mail" class="w-4 h-4"></i>
|
||
<span>写给那时的自己</span>
|
||
</button>
|
||
<button class="text-text-medium hover:text-tech-blue text-sm">编辑</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</main>
|
||
|
||
<!-- Footer -->
|
||
<footer class="bg-white">
|
||
<div class="container mx-auto px-6 py-12">
|
||
<div class="mt-12 border-t border-gray-200 pt-8 text-center text-text-medium">
|
||
<p>© 2025 开心APP. All Rights Reserved. 来自"开心"星球的温柔科技。</p>
|
||
</div>
|
||
</div>
|
||
</footer>
|
||
|
||
<!-- Add Life Event Modal -->
|
||
<div
|
||
id="add-event-modal"
|
||
class="fixed inset-0 bg-gray-900/80 backdrop-blur-sm z-[9998] items-center justify-center p-4 transition-opacity duration-300"
|
||
:class="{ 'hidden': !showModal }"
|
||
>
|
||
<div class="bg-light-gray rounded-2xl shadow-2xl w-full max-w-lg transform transition-all duration-300 scale-95 opacity-0" id="add-event-modal-content">
|
||
<form @submit.prevent="addLifeEvent">
|
||
<div class="p-6 border-b border-gray-200">
|
||
<h3 class="text-2xl font-bold text-text-dark flex items-center gap-3">
|
||
<i data-lucide="feather" class="text-tech-blue"></i>记录一件人生大事
|
||
</h3>
|
||
</div>
|
||
<div class="p-6 space-y-5">
|
||
<div>
|
||
<label for="event-date" class="block text-sm font-medium text-text-medium mb-1.5">事件发生日期</label>
|
||
<input
|
||
type="date"
|
||
id="event-date"
|
||
v-model="newEvent.date"
|
||
class="w-full px-4 py-2.5 border border-gray-300 rounded-lg focus:ring-2 focus:ring-tech-blue focus:border-transparent transition"
|
||
required
|
||
>
|
||
</div>
|
||
<div>
|
||
<label for="event-title" class="block text-sm font-medium text-text-medium mb-1.5">事件标题</label>
|
||
<input
|
||
type="text"
|
||
id="event-title"
|
||
v-model="newEvent.title"
|
||
class="w-full px-4 py-2.5 border border-gray-300 rounded-lg focus:ring-2 focus:ring-tech-blue focus:border-transparent transition"
|
||
placeholder="例如:大学毕业"
|
||
required
|
||
>
|
||
</div>
|
||
<div>
|
||
<label for="event-content" class="block text-sm font-medium text-text-medium mb-1.5">详细内容</label>
|
||
<textarea
|
||
id="event-content"
|
||
v-model="newEvent.content"
|
||
rows="5"
|
||
class="w-full px-4 py-2.5 border border-gray-300 rounded-lg focus:ring-2 focus:ring-tech-blue focus:border-transparent transition"
|
||
placeholder="详细描述一下当时发生了什么,以及你的感受..."
|
||
required
|
||
></textarea>
|
||
</div>
|
||
<div>
|
||
<label class="block text-sm font-medium text-text-medium mb-1.5">这是...?</label>
|
||
<div class="flex gap-4">
|
||
<label class="flex items-center gap-2 cursor-pointer">
|
||
<input
|
||
type="radio"
|
||
v-model="newEvent.type"
|
||
value="positive"
|
||
class="form-radio text-emerald-500 focus:ring-emerald-400"
|
||
>
|
||
<span class="text-emerald-600 font-medium">正面/高光事件</span>
|
||
</label>
|
||
<label class="flex items-center gap-2 cursor-pointer">
|
||
<input
|
||
type="radio"
|
||
v-model="newEvent.type"
|
||
value="negative"
|
||
class="form-radio text-red-500 focus:ring-red-400"
|
||
>
|
||
<span class="text-red-600 font-medium">负面/创伤事件</span>
|
||
</label>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="p-6 bg-white rounded-b-2xl flex justify-end items-center gap-4">
|
||
<button
|
||
type="button"
|
||
@click="closeModal"
|
||
class="px-5 py-2.5 rounded-lg text-text-medium hover:bg-gray-100 transition"
|
||
>
|
||
取消
|
||
</button>
|
||
<button
|
||
type="submit"
|
||
class="bg-tech-blue text-white px-6 py-2.5 rounded-lg font-semibold hover:bg-blue-600 transition-all duration-300"
|
||
>
|
||
保存并获取AI分析
|
||
</button>
|
||
</div>
|
||
</form>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</template>
|
||
|
||
<script setup lang="ts">
|
||
import { ref, onMounted } from 'vue'
|
||
|
||
// 响应式数据
|
||
const mobileMenuOpen = ref(false)
|
||
const showModal = ref(false)
|
||
const lifeEvents = ref([
|
||
{
|
||
id: 1,
|
||
title: '大学毕业',
|
||
date: '2023年6月',
|
||
content: '经过四年的努力,终于完成了大学学业。这是一个重要的里程碑,标志着学生时代的结束和新生活的开始。',
|
||
type: 'positive'
|
||
}
|
||
])
|
||
|
||
const newEvent = ref({
|
||
date: '',
|
||
title: '',
|
||
content: '',
|
||
type: 'positive'
|
||
})
|
||
|
||
// 切换移动端菜单
|
||
const toggleMobileMenu = () => {
|
||
mobileMenuOpen.value = !mobileMenuOpen.value
|
||
}
|
||
|
||
// 显示添加事件模态框
|
||
const showAddEventModal = () => {
|
||
showModal.value = true
|
||
}
|
||
|
||
// 关闭模态框
|
||
const closeModal = () => {
|
||
showModal.value = false
|
||
// 重置表单
|
||
newEvent.value = {
|
||
date: '',
|
||
title: '',
|
||
content: '',
|
||
type: 'positive'
|
||
}
|
||
}
|
||
|
||
// 添加人生事件
|
||
const addLifeEvent = () => {
|
||
// TODO: 实现添加人生事件逻辑
|
||
console.log('添加人生事件:', newEvent.value)
|
||
closeModal()
|
||
}
|
||
|
||
// 写信给那时的自己
|
||
const writeLetter = () => {
|
||
// TODO: 实现写信功能
|
||
console.log('写信给那时的自己')
|
||
}
|
||
|
||
// 生命周期
|
||
onMounted(() => {
|
||
// 初始化Lucide图标
|
||
if (window.lucide) {
|
||
window.lucide.createIcons()
|
||
}
|
||
})
|
||
</script>
|
||
|
||
<style scoped>
|
||
/* 导入原始样式变量 */
|
||
:root {
|
||
--tech-blue: #4A90E2;
|
||
--warm-orange: #F5A623;
|
||
--white: #FFFFFF;
|
||
--light-gray: #F7F8FA;
|
||
--text-dark: #333333;
|
||
--text-medium: #888888;
|
||
}
|
||
|
||
/* 应用原始样式类 */
|
||
.bg-tech-blue { background-color: var(--tech-blue); }
|
||
.bg-warm-orange { background-color: var(--warm-orange); }
|
||
.bg-light-gray { background-color: var(--light-gray); }
|
||
.text-tech-blue { color: var(--tech-blue); }
|
||
.text-text-dark { color: var(--text-dark); }
|
||
.text-text-medium { color: var(--text-medium); }
|
||
.border-tech-blue { border-color: var(--tech-blue); }
|
||
|
||
.life-trajectory-page {
|
||
font-family: 'Noto Sans SC', sans-serif;
|
||
background-color: var(--light-gray);
|
||
color: var(--text-dark);
|
||
}
|
||
|
||
/* 动画样式 */
|
||
.animate-fade-in-up {
|
||
animation: fade-in-up 0.8s ease-out forwards;
|
||
opacity: 0;
|
||
}
|
||
|
||
@keyframes fade-in-up {
|
||
from {
|
||
opacity: 0;
|
||
transform: translateY(20px);
|
||
}
|
||
to {
|
||
opacity: 1;
|
||
transform: translateY(0);
|
||
}
|
||
}
|
||
|
||
/* 全局样式 */
|
||
body {
|
||
font-family: 'Noto Sans SC', sans-serif;
|
||
}
|
||
</style> |