Spaces:
Running
Running
<html lang="en"> | |
<head> | |
<meta charset="UTF-8"> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
<title>Skyai - AI-Powered Goal Achievement</title> | |
<script src="https://cdn.tailwindcss.com"></script> | |
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> | |
<style> | |
@keyframes float { | |
0% { transform: translateY(0px); } | |
50% { transform: translateY(-10px); } | |
100% { transform: translateY(0px); } | |
} | |
.floating { | |
animation: float 3s ease-in-out infinite; | |
} | |
.progress-bar { | |
transition: width 0.5s ease-in-out; | |
} | |
.task-card { | |
transition: all 0.3s ease; | |
} | |
.task-card:hover { | |
transform: translateY(-3px); | |
box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1); | |
} | |
.map-node { | |
transition: all 0.3s ease; | |
} | |
.map-node.active { | |
transform: scale(1.1); | |
box-shadow: 0 0 0 4px rgba(99, 102, 241, 0.3); | |
} | |
.streak-pulse { | |
animation: pulse 2s infinite; | |
} | |
@keyframes pulse { | |
0% { box-shadow: 0 0 0 0 rgba(234, 88, 12, 0.7); } | |
70% { box-shadow: 0 0 0 10px rgba(234, 88, 12, 0); } | |
100% { box-shadow: 0 0 0 0 rgba(234, 88, 12, 0); } | |
} | |
.modal { | |
display: none; | |
position: fixed; | |
top: 0; | |
left: 0; | |
width: 100%; | |
height: 100%; | |
background-color: rgba(0,0,0,0.5); | |
z-index: 1000; | |
justify-content: center; | |
align-items: center; | |
} | |
.modal-content { | |
background-color: white; | |
padding: 20px; | |
border-radius: 10px; | |
width: 90%; | |
max-width: 400px; | |
max-height: 80vh; | |
overflow-y: auto; | |
} | |
.chat-message { | |
max-width: 80%; | |
margin-bottom: 10px; | |
padding: 8px 12px; | |
border-radius: 12px; | |
} | |
.user-message { | |
background-color: #6366f1; | |
color: white; | |
margin-left: auto; | |
border-bottom-right-radius: 4px; | |
} | |
.ai-message { | |
background-color: #f3f4f6; | |
color: #1f2937; | |
margin-right: auto; | |
border-bottom-left-radius: 4px; | |
} | |
</style> | |
</head> | |
<body class="bg-gray-50 font-sans"> | |
<!-- App Container --> | |
<div class="max-w-md mx-auto bg-white min-h-screen shadow-lg overflow-hidden"> | |
<!-- Header --> | |
<header class="bg-gradient-to-r from-indigo-500 to-purple-600 text-white p-4"> | |
<div class="flex justify-between items-center"> | |
<div class="flex items-center space-x-2"> | |
<div class="w-8 h-8 bg-white rounded-full flex items-center justify-center"> | |
<i class="fas fa-cloud text-indigo-500 text-lg"></i> | |
</div> | |
<h1 class="font-bold text-xl">Skyai</h1> | |
</div> | |
<div class="flex items-center space-x-3"> | |
<div class="relative"> | |
<div class="w-8 h-8 bg-yellow-400 rounded-full flex items-center justify-center streak-pulse"> | |
<span class="font-bold text-orange-800" id="streak-count">7</span> | |
</div> | |
<div class="absolute -top-1 -right-1 bg-red-500 text-white text-xs rounded-full w-4 h-4 flex items-center justify-center">🔥</div> | |
</div> | |
<div class="w-8 h-8 bg-white bg-opacity-20 rounded-full flex items-center justify-center"> | |
<i class="fas fa-bell"></i> | |
</div> | |
</div> | |
</div> | |
</header> | |
<!-- Main Content --> | |
<main class="p-4 pb-20" id="main-content"> | |
<!-- User Progress --> | |
<div class="bg-white rounded-xl shadow-md p-4 mb-4"> | |
<div class="flex justify-between items-center mb-2"> | |
<div> | |
<span class="text-sm text-gray-500">Level <span id="user-level">3</span> Explorer</span> | |
<h3 class="font-bold" id="username">Alex Founder</h3> | |
</div> | |
<div class="text-right"> | |
<div class="text-xs text-gray-500">XP: <span id="current-xp">245</span>/<span id="max-xp">400</span></div> | |
<div class="w-full bg-gray-200 rounded-full h-2"> | |
<div class="bg-indigo-500 h-2 rounded-full progress-bar" id="xp-bar" style="width: 61%"></div> | |
</div> | |
</div> | |
</div> | |
</div> | |
<!-- Current Goal --> | |
<div class="bg-gradient-to-r from-blue-50 to-indigo-50 rounded-xl shadow-md p-4 mb-6 border border-blue-100"> | |
<div class="flex justify-between items-start mb-2"> | |
<div> | |
<span class="text-xs font-semibold bg-blue-100 text-blue-800 px-2 py-1 rounded-full">ACTIVE GOAL</span> | |
<h3 class="font-bold mt-2 text-lg" id="current-goal-title">Reach $10k MRR</h3> | |
</div> | |
<button class="text-blue-500" onclick="showEditGoalModal()"> | |
<i class="fas fa-ellipsis-h"></i> | |
</button> | |
</div> | |
<p class="text-sm text-gray-600 mb-3" id="current-goal-description">Current: $3,200 MRR → Goal: $10,000 MRR</p> | |
<!-- Progress Map --> | |
<div class="relative h-24 mb-4"> | |
<div class="absolute top-1/2 left-0 right-0 h-1 bg-gray-200 transform -translate-y-1/2"></div> | |
<div class="absolute top-1/2 left-0 h-1 bg-indigo-500 transform -translate-y-1/2" id="goal-progress-bar" style="width: 32%"></div> | |
<div class="absolute top-1/2 left-0 transform -translate-y-1/2 -translate-x-1/2"> | |
<div class="w-6 h-6 bg-indigo-500 rounded-full flex items-center justify-center text-white text-xs map-node active" onclick="selectMapNode(0)">1</div> | |
<div class="text-xs text-center mt-1">Start</div> | |
</div> | |
<div class="absolute top-1/2 left-1/3 transform -translate-y-1/2 -translate-x-1/2"> | |
<div class="w-6 h-6 bg-indigo-500 rounded-full flex items-center justify-center text-white text-xs map-node" onclick="selectMapNode(1)">2</div> | |
<div class="text-xs text-center mt-1">$5k</div> | |
</div> | |
<div class="absolute top-1/2 left-2/3 transform -translate-y-1/2 -translate-x-1/2"> | |
<div class="w-6 h-6 bg-gray-300 rounded-full flex items-center justify-center text-gray-600 text-xs map-node" onclick="selectMapNode(2)">3</div> | |
<div class="text-xs text-center mt-1">$7.5k</div> | |
</div> | |
<div class="absolute top-1/2 right-0 transform -translate-y-1/2 translate-x-1/2"> | |
<div class="w-6 h-6 bg-gray-300 rounded-full flex items-center justify-center text-gray-600 text-xs map-node" onclick="selectMapNode(3)">4</div> | |
<div class="text-xs text-center mt-1">Goal</div> | |
</div> | |
</div> | |
<button class="w-full bg-indigo-500 hover:bg-indigo-600 text-white py-2 px-4 rounded-lg font-medium transition duration-200" onclick="showFullJourney()"> | |
See Full Journey | |
</button> | |
</div> | |
<!-- AI Assistant --> | |
<div class="bg-white rounded-xl shadow-md p-4 mb-6"> | |
<div class="flex items-center mb-3"> | |
<div class="w-10 h-10 bg-purple-100 rounded-full flex items-center justify-center mr-3"> | |
<i class="fas fa-robot text-purple-500 text-xl"></i> | |
</div> | |
<div> | |
<h3 class="font-bold">SkyAI Assistant</h3> | |
<p class="text-xs text-gray-500">Ready to help you progress</p> | |
</div> | |
</div> | |
<div class="bg-gray-50 rounded-lg p-3 mb-3"> | |
<p class="text-sm" id="ai-recommendation">"Based on your current progress, I recommend focusing on these high-leverage tasks to move toward $10k MRR:"</p> | |
</div> | |
<button class="w-full bg-gradient-to-r from-purple-500 to-indigo-500 hover:from-purple-600 hover:to-indigo-600 text-white py-2 px-4 rounded-lg font-medium transition duration-200 flex items-center justify-center" onclick="showAIChatModal()"> | |
<i class="fas fa-comment-dots mr-2"></i> Chat with AI | |
</button> | |
</div> | |
<!-- Priority Tasks --> | |
<div class="mb-6"> | |
<div class="flex justify-between items-center mb-3"> | |
<h2 class="font-bold text-lg">Priority Tasks</h2> | |
<button class="text-sm text-indigo-500" onclick="showAllTasks('priority')">View All</button> | |
</div> | |
<div class="space-y-3" id="priority-tasks"> | |
<!-- Task 1 --> | |
<div class="task-card bg-white rounded-lg shadow-md p-4 border-l-4 border-blue-500"> | |
<div class="flex justify-between items-start mb-2"> | |
<h3 class="font-medium">Optimize pricing page conversion</h3> | |
<span class="text-xs bg-blue-100 text-blue-800 px-2 py-1 rounded-full">HIGH IMPACT</span> | |
</div> | |
<p class="text-sm text-gray-600 mb-3">Current conversion: 2.1% → Target: 4.5%</p> | |
<div class="flex justify-between items-center"> | |
<div class="flex space-x-2"> | |
<span class="text-xs bg-green-100 text-green-800 px-2 py-1 rounded-full">DO</span> | |
<span class="text-xs bg-yellow-100 text-yellow-800 px-2 py-1 rounded-full">UX</span> | |
</div> | |
<div class="flex space-x-2"> | |
<button class="text-blue-500 text-sm" onclick="shareTask('Optimize pricing page conversion')"><i class="fas fa-share-alt"></i></button> | |
<button class="text-green-500 text-sm" onclick="completeTask(this, 25)"><i class="fas fa-check-circle"></i></button> | |
</div> | |
</div> | |
</div> | |
<!-- Task 2 --> | |
<div class="task-card bg-white rounded-lg shadow-md p-4 border-l-4 border-orange-500"> | |
<div class="flex justify-between items-start mb-2"> | |
<h3 class="font-medium">Create case study for top customer</h3> | |
<span class="text-xs bg-orange-100 text-orange-800 px-2 py-1 rounded-full">MEDIUM IMPACT</span> | |
</div> | |
<p class="text-sm text-gray-600 mb-3">Will help with sales conversations</p> | |
<div class="flex justify-between items-center"> | |
<div class="flex space-x-2"> | |
<span class="text-xs bg-green-100 text-green-800 px-2 py-1 rounded-full">DO</span> | |
<span class="text-xs bg-purple-100 text-purple-800 px-2 py-1 rounded-full">CONTENT</span> | |
</div> | |
<div class="flex space-x-2"> | |
<button class="text-blue-500 text-sm" onclick="shareTask('Create case study for top customer')"><i class="fas fa-share-alt"></i></button> | |
<button class="text-green-500 text-sm" onclick="completeTask(this, 15)"><i class="fas fa-check-circle"></i></button> | |
</div> | |
</div> | |
</div> | |
</div> | |
</div> | |
<!-- Delegation Tasks --> | |
<div class="mb-6"> | |
<div class="flex justify-between items-center mb-3"> | |
<h2 class="font-bold text-lg">Tasks to Delegate</h2> | |
<button class="text-sm text-indigo-500" onclick="showAllTasks('delegate')">View All</button> | |
</div> | |
<div class="space-y-3" id="delegate-tasks"> | |
<!-- Task 1 --> | |
<div class="task-card bg-white rounded-lg shadow-md p-4 border-l-4 border-gray-400"> | |
<div class="flex justify-between items-start mb-2"> | |
<h3 class="font-medium">Update social media banners</h3> | |
<span class="text-xs bg-gray-100 text-gray-800 px-2 py-1 rounded-full">LOW IMPACT</span> | |
</div> | |
<p class="text-sm text-gray-600 mb-3">Consistent branding across platforms</p> | |
<div class="flex justify-between items-center"> | |
<div class="flex space-x-2"> | |
<span class="text-xs bg-red-100 text-red-800 px-2 py-1 rounded-full">DELEGATE</span> | |
<span class="text-xs bg-blue-100 text-blue-800 px-2 py-1 rounded-full">DESIGN</span> | |
</div> | |
<div class="flex space-x-2"> | |
<button class="text-blue-500 text-sm" onclick="assignTask('Update social media banners')"><i class="fas fa-user-plus"></i></button> | |
<button class="text-blue-500 text-sm" onclick="sendTask('Update social media banners')"><i class="fas fa-paper-plane"></i></button> | |
</div> | |
</div> | |
</div> | |
</div> | |
</div> | |
</main> | |
<!-- Bottom Navigation --> | |
<nav class="fixed bottom-0 left-0 right-0 bg-white shadow-lg border-t border-gray-200 max-w-md mx-auto"> | |
<div class="flex justify-around p-3"> | |
<a href="#" class="text-indigo-500 flex flex-col items-center" onclick="showHome()"> | |
<i class="fas fa-home text-xl"></i> | |
<span class="text-xs mt-1">Home</span> | |
</a> | |
<a href="#" class="text-gray-500 flex flex-col items-center" onclick="showJourney()"> | |
<i class="fas fa-map text-xl"></i> | |
<span class="text-xs mt-1">Journey</span> | |
</a> | |
<a href="#" class="text-gray-500 flex flex-col items-center" onclick="showAddTaskModal()"> | |
<div class="relative"> | |
<i class="fas fa-plus-circle text-3xl text-indigo-500 floating" style="margin-top: -20px;"></i> | |
</div> | |
</a> | |
<a href="#" class="text-gray-500 flex flex-col items-center" onclick="showCommunity()"> | |
<i class="fas fa-users text-xl"></i> | |
<span class="text-xs mt-1">Community</span> | |
</a> | |
<a href="#" class="text-gray-500 flex flex-col items-center" onclick="showProfile()"> | |
<i class="fas fa-user text-xl"></i> | |
<span class="text-xs mt-1">Profile</span> | |
</a> | |
</div> | |
</nav> | |
<!-- Modals --> | |
<!-- Edit Goal Modal --> | |
<div class="modal" id="edit-goal-modal"> | |
<div class="modal-content"> | |
<div class="flex justify-between items-center mb-4"> | |
<h3 class="font-bold text-lg">Edit Goal</h3> | |
<button onclick="hideModal('edit-goal-modal')" class="text-gray-500"><i class="fas fa-times"></i></button> | |
</div> | |
<div class="mb-4"> | |
<label class="block text-sm font-medium text-gray-700 mb-1">Goal Title</label> | |
<input type="text" id="edit-goal-title" class="w-full p-2 border border-gray-300 rounded-lg" value="Reach $10k MRR"> | |
</div> | |
<div class="mb-4"> | |
<label class="block text-sm font-medium text-gray-700 mb-1">Current Status</label> | |
<input type="text" id="edit-current-status" class="w-full p-2 border border-gray-300 rounded-lg" value="$3,200 MRR"> | |
</div> | |
<div class="mb-4"> | |
<label class="block text-sm font-medium text-gray-700 mb-1">Target Goal</label> | |
<input type="text" id="edit-target-goal" class="w-full p-2 border border-gray-300 rounded-lg" value="$10,000 MRR"> | |
</div> | |
<div class="flex justify-end space-x-2"> | |
<button onclick="deleteGoal()" class="px-4 py-2 bg-red-500 text-white rounded-lg">Delete</button> | |
<button onclick="saveGoal()" class="px-4 py-2 bg-indigo-500 text-white rounded-lg">Save</button> | |
</div> | |
</div> | |
</div> | |
<!-- AI Chat Modal --> | |
<div class="modal" id="ai-chat-modal"> | |
<div class="modal-content"> | |
<div class="flex justify-between items-center mb-4"> | |
<h3 class="font-bold text-lg">AI Assistant</h3> | |
<button onclick="hideModal('ai-chat-modal')" class="text-gray-500"><i class="fas fa-times"></i></button> | |
</div> | |
<div class="mb-4 h-64 overflow-y-auto" id="chat-messages"> | |
<div class="chat-message ai-message"> | |
Hi there! I'm your SkyAI assistant. How can I help you with your goal today? | |
</div> | |
</div> | |
<div class="flex"> | |
<input type="text" id="chat-input" class="flex-1 p-2 border border-gray-300 rounded-l-lg" placeholder="Ask me anything..."> | |
<button onclick="sendChatMessage()" class="px-4 py-2 bg-indigo-500 text-white rounded-r-lg"><i class="fas fa-paper-plane"></i></button> | |
</div> | |
</div> | |
</div> | |
<!-- Add Task Modal --> | |
<div class="modal" id="add-task-modal"> | |
<div class="modal-content"> | |
<div class="flex justify-between items-center mb-4"> | |
<h3 class="font-bold text-lg">Add New Task</h3> | |
<button onclick="hideModal('add-task-modal')" class="text-gray-500"><i class="fas fa-times"></i></button> | |
</div> | |
<div class="mb-4"> | |
<label class="block text-sm font-medium text-gray-700 mb-1">Task Name</label> | |
<input type="text" id="task-name" class="w-full p-2 border border-gray-300 rounded-lg" placeholder="What needs to be done?"> | |
</div> | |
<div class="mb-4"> | |
<label class="block text-sm font-medium text-gray-700 mb-1">Description</label> | |
<textarea id="task-description" class="w-full p-2 border border-gray-300 rounded-lg" placeholder="Details about the task"></textarea> | |
</div> | |
<div class="mb-4"> | |
<label class="block text-sm font-medium text-gray-700 mb-1">Priority</label> | |
<select id="task-priority" class="w-full p-2 border border-gray-300 rounded-lg"> | |
<option value="high">High Impact</option> | |
<option value="medium">Medium Impact</option> | |
<option value="low">Low Impact</option> | |
</select> | |
</div> | |
<div class="mb-4"> | |
<label class="block text-sm font-medium text-gray-700 mb-1">Action</label> | |
<select id="task-action" class="w-full p-2 border border-gray-300 rounded-lg"> | |
<option value="do">Do (High Priority)</option> | |
<option value="delegate">Delegate</option> | |
</select> | |
</div> | |
<div class="mb-4"> | |
<label class="block text-sm font-medium text-gray-700 mb-1">Category</label> | |
<select id="task-category" class="w-full p-2 border border-gray-300 rounded-lg"> | |
<option value="ux">UX</option> | |
<option value="content">Content</option> | |
<option value="design">Design</option> | |
<option value="marketing">Marketing</option> | |
<option value="development">Development</option> | |
</select> | |
</div> | |
<button onclick="addNewTask()" class="w-full py-2 bg-indigo-500 text-white rounded-lg">Add Task</button> | |
</div> | |
</div> | |
<!-- Profile Modal --> | |
<div class="modal" id="profile-modal"> | |
<div class="modal-content"> | |
<div class="flex justify-between items-center mb-4"> | |
<h3 class="font-bold text-lg">Your Profile</h3> | |
<button onclick="hideModal('profile-modal')" class="text-gray-500"><i class="fas fa-times"></i></button> | |
</div> | |
<div class="mb-4"> | |
<label class="block text-sm font-medium text-gray-700 mb-1">Name</label> | |
<input type="text" id="profile-name" class="w-full p-2 border border-gray-300 rounded-lg" value="Alex Founder"> | |
</div> | |
<div class="mb-4"> | |
<label class="block text-sm font-medium text-gray-700 mb-1">Email</label> | |
<input type="email" id="profile-email" class="w-full p-2 border border-gray-300 rounded-lg" value="[email protected]"> | |
</div> | |
<div class="mb-4"> | |
<label class="block text-sm font-medium text-gray-700 mb-1">Deepseek API Key</label> | |
<input type="password" id="api-key" class="w-full p-2 border border-gray-300 rounded-lg" placeholder="Enter your Deepseek API key"> | |
<p class="text-xs text-gray-500 mt-1">This key is stored locally in your browser only</p> | |
</div> | |
<div class="mb-4"> | |
<label class="block text-sm font-medium text-gray-700 mb-1">Current Streak</label> | |
<input type="number" id="profile-streak" class="w-full p-2 border border-gray-300 rounded-lg" value="7"> | |
</div> | |
<div class="mb-4"> | |
<label class="block text-sm font-medium text-gray-700 mb-1">Current Level</label> | |
<input type="number" id="profile-level" class="w-full p-2 border border-gray-300 rounded-lg" value="3"> | |
</div> | |
<div class="mb-4"> | |
<label class="block text-sm font-medium text-gray-700 mb-1">Current XP</label> | |
<input type="number" id="profile-xp" class="w-full p-2 border border-gray-300 rounded-lg" value="245"> | |
</div> | |
<div class="mb-4"> | |
<label class="block text-sm font-medium text-gray-700 mb-1">Max XP</label> | |
<input type="number" id="profile-max-xp" class="w-full p-2 border border-gray-300 rounded-lg" value="400"> | |
</div> | |
<button onclick="saveProfile()" class="w-full py-2 bg-indigo-500 text-white rounded-lg">Save Profile</button> | |
</div> | |
</div> | |
<!-- Share Task Modal --> | |
<div class="modal" id="share-task-modal"> | |
<div class="modal-content"> | |
<div class="flex justify-between items-center mb-4"> | |
<h3 class="font-bold text-lg">Share Task</h3> | |
<button onclick="hideModal('share-task-modal')" class="text-gray-500"><i class="fas fa-times"></i></button> | |
</div> | |
<div class="mb-4"> | |
<label class="block text-sm font-medium text-gray-700 mb-1">Task</label> | |
<input type="text" id="share-task-name" class="w-full p-2 border border-gray-300 rounded-lg" readonly> | |
</div> | |
<div class="mb-4"> | |
<label class="block text-sm font-medium text-gray-700 mb-1">Share Via</label> | |
<select id="share-method" class="w-full p-2 border border-gray-300 rounded-lg"> | |
<option value="email">Email</option> | |
<option value="slack">Slack</option> | |
<option value="link">Copy Link</option> | |
</select> | |
</div> | |
<div class="mb-4" id="share-email-field"> | |
<label class="block text-sm font-medium text-gray-700 mb-1">Email Address</label> | |
<input type="email" id="share-email" class="w-full p-2 border border-gray-300 rounded-lg" placeholder="[email protected]"> | |
</div> | |
<div class="mb-4" id="share-message-field"> | |
<label class="block text-sm font-medium text-gray-700 mb-1">Message</label> | |
<textarea id="share-message" class="w-full p-2 border border-gray-300 rounded-lg" placeholder="Optional message"></textarea> | |
</div> | |
<button onclick="confirmShareTask()" class="w-full py-2 bg-indigo-500 text-white rounded-lg">Share Task</button> | |
</div> | |
</div> | |
<!-- Full Journey Modal --> | |
<div class="modal" id="journey-modal"> | |
<div class="modal-content"> | |
<div class="flex justify-between items-center mb-4"> | |
<h3 class="font-bold text-lg">Your Goal Journey</h3> | |
<button onclick="hideModal('journey-modal')" class="text-gray-500"><i class="fas fa-times"></i></button> | |
</div> | |
<div class="mb-4"> | |
<h4 class="font-semibold mb-2" id="journey-goal-title">Reach $10k MRR</h4> | |
<div class="relative h-12 mb-6"> | |
<div class="absolute top-1/2 left-0 right-0 h-2 bg-gray-200 transform -translate-y-1/2"></div> | |
<div class="absolute top-1/2 left-0 h-2 bg-indigo-500 transform -translate-y-1/2" style="width: 32%"></div> | |
<div class="absolute top-1/2 left-0 transform -translate-y-1/2 -translate-x-1/2"> | |
<div class="w-6 h-6 bg-indigo-500 rounded-full flex items-center justify-center text-white text-xs">1</div> | |
<div class="text-xs text-center mt-1">Start</div> | |
</div> | |
<div class="absolute top-1/2 left-1/3 transform -translate-y-1/2 -translate-x-1/2"> | |
<div class="w-6 h-6 bg-indigo-500 rounded-full flex items-center justify-center text-white text-xs">2</div> | |
<div class="text-xs text-center mt-1">$5k</div> | |
</div> | |
<div class="absolute top-1/2 left-2/3 transform -translate-y-1/2 -translate-x-1/2"> | |
<div class="w-6 h-6 bg-gray-300 rounded-full flex items-center justify-center text-gray-600 text-xs">3</div> | |
<div class="text-xs text-center mt-1">$7.5k</div> | |
</div> | |
<div class="absolute top-1/2 right-0 transform -translate-y-1/2 translate-x-1/2"> | |
<div class="w-6 h-6 bg-gray-300 rounded-full flex items-center justify-center text-gray-600 text-xs">4</div> | |
<div class="text-xs text-center mt-1">Goal</div> | |
</div> | |
</div> | |
</div> | |
<div class="mb-4"> | |
<h4 class="font-semibold mb-2">Milestones</h4> | |
<div class="space-y-3"> | |
<div class="flex items-start"> | |
<div class="w-6 h-6 bg-indigo-100 rounded-full flex items-center justify-center text-indigo-500 mr-2 mt-1"> | |
<i class="fas fa-check text-xs"></i> | |
</div> | |
<div> | |
<h5 class="font-medium">Started the journey</h5> | |
<p class="text-sm text-gray-600">You set your goal to reach $10k MRR</p> | |
<p class="text-xs text-gray-500">3 days ago</p> | |
</div> | |
</div> | |
<div class="flex items-start"> | |
<div class="w-6 h-6 bg-indigo-100 rounded-full flex items-center justify-center text-indigo-500 mr-2 mt-1"> | |
<i class="fas fa-check text-xs"></i> | |
</div> | |
<div> | |
<h5 class="font-medium">Reached $3k MRR</h5> | |
<p class="text-sm text-gray-600">You hit your first milestone</p> | |
<p class="text-xs text-gray-500">1 day ago</p> | |
</div> | |
</div> | |
<div class="flex items-start"> | |
<div class="w-6 h-6 bg-gray-100 rounded-full flex items-center justify-center text-gray-400 mr-2 mt-1"> | |
<i class="fas fa-lock text-xs"></i> | |
</div> | |
<div> | |
<h5 class="font-medium text-gray-500">Reach $5k MRR</h5> | |
<p class="text-sm text-gray-500">Next milestone</p> | |
</div> | |
</div> | |
</div> | |
</div> | |
<button onclick="hideModal('journey-modal')" class="w-full py-2 bg-indigo-500 text-white rounded-lg">Close</button> | |
</div> | |
</div> | |
</div> | |
<script> | |
// App State | |
const appState = { | |
currentView: 'home', | |
tasks: [ | |
{ | |
id: 1, | |
name: "Optimize pricing page conversion", | |
description: "Current conversion: 2.1% → Target: 4.5%", | |
priority: "high", | |
action: "do", | |
category: "ux", | |
completed: false | |
}, | |
{ | |
id: 2, | |
name: "Create case study for top customer", | |
description: "Will help with sales conversations", | |
priority: "medium", | |
action: "do", | |
category: "content", | |
completed: false | |
}, | |
{ | |
id: 3, | |
name: "Update social media banners", | |
description: "Consistent branding across platforms", | |
priority: "low", | |
action: "delegate", | |
category: "design", | |
completed: false | |
} | |
], | |
goal: { | |
title: "Reach $10k MRR", | |
current: "$3,200 MRR", | |
target: "$10,000 MRR", | |
progress: 32 | |
}, | |
user: { | |
name: "Alex Founder", | |
email: "[email protected]", | |
level: 3, | |
xp: 245, | |
maxXp: 400, | |
streak: 7, | |
apiKey: "" | |
}, | |
chatMessages: [ | |
{ | |
sender: "ai", | |
content: "Hi there! I'm your SkyAI assistant. How can I help you with your goal today?" | |
} | |
], | |
currentTaskToShare: null | |
}; | |
// Initialize the app | |
document.addEventListener('DOMContentLoaded', function() { | |
loadStateFromLocalStorage(); | |
renderCurrentView(); | |
updateXPBar(); | |
// Set up event listeners for share method change | |
document.getElementById('share-method').addEventListener('change', function() { | |
const method = this.value; | |
const emailField = document.getElementById('share-email-field'); | |
const messageField = document.getElementById('share-message-field'); | |
if (method === 'email') { | |
emailField.style.display = 'block'; | |
messageField.style.display = 'block'; | |
} else if (method === 'slack') { | |
emailField.style.display = 'none'; | |
messageField.style.display = 'block'; | |
} else { | |
emailField.style.display = 'none'; | |
messageField.style.display = 'none'; | |
} | |
}); | |
}); | |
// Load state from localStorage | |
function loadStateFromLocalStorage() { | |
const savedState = localStorage.getItem('skyaiState'); | |
if (savedState) { | |
Object.assign(appState, JSON.parse(savedState)); | |
} | |
updateUIFromState(); | |
} | |
// Save state to localStorage | |
function saveStateToLocalStorage() { | |
localStorage.setItem('skyaiState', JSON.stringify(appState)); | |
} | |
// Update UI from app state | |
function updateUIFromState() { | |
// Update user info | |
document.getElementById('username').textContent = appState.user.name; | |
document.getElementById('user-level').textContent = appState.user.level; | |
document.getElementById('current-xp').textContent = appState.user.xp; | |
document.getElementById('max-xp').textContent = appState.user.maxXp; | |
document.getElementById('streak-count').textContent = appState.user.streak; | |
// Update goal info | |
document.getElementById('current-goal-title').textContent = appState.goal.title; | |
document.getElementById('current-goal-description').textContent = `Current: ${appState.goal.current} → Goal: ${appState.goal.target}`; | |
document.getElementById('goal-progress-bar').style.width = `${appState.goal.progress}%`; | |
// Update profile form | |
document.getElementById('profile-name').value = appState.user.name; | |
document.getElementById('profile-email').value = appState.user.email; | |
document.getElementById('api-key').value = appState.user.apiKey; | |
document.getElementById('profile-streak').value = appState.user.streak; | |
document.getElementById('profile-level').value = appState.user.level; | |
document.getElementById('profile-xp').value = appState.user.xp; | |
document.getElementById('profile-max-xp').value = appState.user.maxXp; | |
// Update edit goal form | |
document.getElementById('edit-goal-title').value = appState.goal.title; | |
document.getElementById('edit-current-status').value = appState.goal.current; | |
document.getElementById('edit-target-goal').value = appState.goal.target; | |
// Update XP bar | |
updateXPBar(); | |
// Update tasks | |
renderTasks(); | |
} | |
// Update XP bar | |
function updateXPBar() { | |
const percentage = (appState.user.xp / appState.user.maxXp) * 100; | |
document.getElementById('xp-bar').style.width = `${percentage}%`; | |
} | |
// Render tasks | |
function renderTasks() { | |
const priorityTasksContainer = document.getElementById('priority-tasks'); | |
const delegateTasksContainer = document.getElementById('delegate-tasks'); | |
// Clear existing tasks | |
priorityTasksContainer.innerHTML = ''; | |
delegateTasksContainer.innerHTML = ''; | |
// Filter and render tasks | |
appState.tasks.filter(task => !task.completed).forEach(task => { | |
const taskElement = createTaskElement(task); | |
if (task.action === 'do') { | |
priorityTasksContainer.appendChild(taskElement); | |
} else { | |
delegateTasksContainer.appendChild(taskElement); | |
} | |
}); | |
} | |
// Create task element | |
function createTaskElement(task) { | |
const taskCard = document.createElement('div'); | |
taskCard.className = 'task-card bg-white rounded-lg shadow-md p-4 border-l-4'; | |
// Set border color based on priority | |
if (task.priority === 'high') { | |
taskCard.classList.add('border-blue-500'); | |
} else if (task.priority === 'medium') { | |
taskCard.classList.add('border-orange-500'); | |
} else { | |
taskCard.classList.add('border-gray-400'); | |
} | |
// Priority badge text and color | |
let priorityText, priorityBg; | |
if (task.priority === 'high') { | |
priorityText = 'HIGH IMPACT'; | |
priorityBg = 'bg-blue-100 text-blue-800'; | |
} else if (task.priority === 'medium') { | |
priorityText = 'MEDIUM IMPACT'; | |
priorityBg = 'bg-orange-100 text-orange-800'; | |
} else { | |
priorityText = 'LOW IMPACT'; | |
priorityBg = 'bg-gray-100 text-gray-800'; | |
} | |
// Action badge text and color | |
const actionText = task.action === 'do' ? 'DO' : 'DELEGATE'; | |
const actionBg = task.action === 'do' ? 'bg-green-100 text-green-800' : 'bg-red-100 text-red-800'; | |
// Category badge text and color | |
let categoryText, categoryBg; | |
switch(task.category) { | |
case 'ux': | |
categoryText = 'UX'; | |
categoryBg = 'bg-yellow-100 text-yellow-800'; | |
break; | |
case 'content': | |
categoryText = 'CONTENT'; | |
categoryBg = 'bg-purple-100 text-purple-800'; | |
break; | |
case 'design': | |
categoryText = 'DESIGN'; | |
categoryBg = 'bg-blue-100 text-blue-800'; | |
break; | |
case 'marketing': | |
categoryText = 'MARKETING'; | |
categoryBg = 'bg-green-100 text-green-800'; | |
break; | |
case 'development': | |
categoryText = 'DEV'; | |
categoryBg = 'bg-indigo-100 text-indigo-800'; | |
break; | |
default: | |
categoryText = task.category.toUpperCase(); | |
categoryBg = 'bg-gray-100 text-gray-800'; | |
} | |
// XP value for completing the task | |
const xpValue = task.priority === 'high' ? 25 : task.priority === 'medium' ? 15 : 10; | |
// Build task card HTML | |
taskCard.innerHTML = ` | |
<div class="flex justify-between items-start mb-2"> | |
<h3 class="font-medium">${task.name}</h3> | |
<span class="text-xs ${priorityBg} px-2 py-1 rounded-full">${priorityText}</span> | |
</div> | |
<p class="text-sm text-gray-600 mb-3">${task.description}</p> | |
<div class="flex justify-between items-center"> | |
<div class="flex space-x-2"> | |
<span class="text-xs ${actionBg} px-2 py-1 rounded-full">${actionText}</span> | |
<span class="text-xs ${categoryBg} px-2 py-1 rounded-full">${categoryText}</span> | |
</div> | |
<div class="flex space-x-2"> | |
<button class="text-blue-500 text-sm" onclick="shareTask('${task.name}')"><i class="fas fa-share-alt"></i></button> | |
${task.action === 'do' ? | |
`<button class="text-green-500 text-sm" onclick="completeTask(this, ${xpValue})"><i class="fas fa-check-circle"></i></button>` : | |
`<button class="text-blue-500 text-sm" onclick="sendTask('${task.name}')"><i class="fas fa-paper-plane"></i></button>` | |
} | |
</div> | |
</div> | |
`; | |
return taskCard; | |
} | |
// Modal functions | |
function showModal(modalId) { | |
document.getElementById(modalId).style.display = 'flex'; | |
} | |
function hideModal(modalId) { | |
document.getElementById(modalId).style.display = 'none'; | |
} | |
// Navigation functions | |
function showHome() { | |
appState.currentView = 'home'; | |
renderCurrentView(); | |
} | |
function showJourney() { | |
showModal('journey-modal'); | |
} | |
function showCommunity() { | |
appState.currentView = 'community'; | |
renderCurrentView(); | |
// In a real app, we would fetch and display community content here | |
alert('Community feature coming soon!'); | |
showHome(); // Fall back to home for now | |
} | |
function showProfile() { | |
showModal('profile-modal'); | |
} | |
function renderCurrentView() { | |
// In a real app, we would render different views here | |
// For this demo, we're mainly using modals, so we just ensure home is shown | |
document.getElementById('main-content').style.display = 'block'; | |
} | |
// Goal functions | |
function showEditGoalModal() { | |
showModal('edit-goal-modal'); | |
} | |
function saveGoal() { | |
appState.goal.title = document.getElementById('edit-goal-title').value; | |
appState.goal.current = document.getElementById('edit-current-status').value; | |
appState.goal.target = document.getElementById('edit-target-goal').value; | |
// Calculate new progress (simplified for demo) | |
const currentValue = parseFloat(appState.goal.current.replace(/[^0-9.]/g, '')); | |
const targetValue = parseFloat(appState.goal.target.replace(/[^0-9.]/g, '')); | |
appState.goal.progress = Math.min(100, Math.round((currentValue / targetValue) * 100)); | |
updateUIFromState(); | |
saveStateToLocalStorage(); | |
hideModal('edit-goal-modal'); | |
// Update AI recommendation | |
updateAIRecommendation(); | |
} | |
function deleteGoal() { | |
if (confirm('Are you sure you want to delete this goal?')) { | |
appState.goal = { | |
title: "New Goal", | |
current: "Current status", | |
target: "Target goal", | |
progress: 0 | |
}; | |
updateUIFromState(); | |
saveStateToLocalStorage(); | |
hideModal('edit-goal-modal'); | |
} | |
} | |
function showFullJourney() { | |
document.getElementById('journey-goal-title').textContent = appState.goal.title; | |
showModal('journey-modal'); | |
} | |
function selectMapNode(index) { | |
const nodes = document.querySelectorAll('.map-node'); | |
nodes.forEach(node => node.classList.remove('active')); | |
nodes[index].classList.add('active'); | |
// In a real app, we might show details for this milestone | |
} | |
// Task functions | |
function showAddTaskModal() { | |
showModal('add-task-modal'); | |
} | |
function addNewTask() { | |
const name = document.getElementById('task-name').value; | |
const description = document.getElementById('task-description').value; | |
const priority = document.getElementById('task-priority').value; | |
const action = document.getElementById('task-action').value; | |
const category = document.getElementById('task-category').value; | |
if (!name) { | |
alert('Please enter a task name'); | |
return; | |
} | |
const newTask = { | |
id: Date.now(), // Simple unique ID | |
name, | |
description: description || 'No description', | |
priority, | |
action, | |
category, | |
completed: false | |
}; | |
appState.tasks.push(newTask); | |
renderTasks(); | |
saveStateToLocalStorage(); | |
hideModal('add-task-modal'); | |
// Reset form | |
document.getElementById('task-name').value = ''; | |
document.getElementById('task-description').value = ''; | |
} | |
function completeTask(button, xp) { | |
const taskCard = button.closest('.task-card'); | |
const taskName = taskCard.querySelector('h3').textContent; | |
// Find and mark task as completed | |
const task = appState.tasks.find(t => t.name === taskName); | |
if (task) { | |
task.completed = true; | |
} | |
// Add XP | |
appState.user.xp += xp; | |
// Check for level up | |
if (appState.user.xp >= appState.user.maxXp) { | |
appState.user.level += 1; | |
appState.user.xp = appState.user.xp - appState.user.maxXp; | |
appState.user.maxXp = Math.round(appState.user.maxXp * 1.5); | |
alert(`Level Up! You're now level ${appState.user.level}`); | |
} | |
// Update streak (simplified for demo) | |
appState.user.streak += 1; | |
// Animate completion | |
taskCard.classList.add('opacity-50'); | |
setTimeout(() => { | |
renderTasks(); | |
updateUIFromState(); | |
saveStateToLocalStorage(); | |
}, 300); | |
} | |
function shareTask(taskName) { | |
appState.currentTaskToShare = taskName; | |
document.getElementById('share-task-name').value = taskName; | |
showModal('share-task-modal'); | |
} | |
function confirmShareTask() { | |
const method = document.getElementById('share-method').value; | |
const taskName = appState.currentTaskToShare; | |
let message = `I'd like to share this task with you: ${taskName}`; | |
if (method === 'email') { | |
const email = document.getElementById('share-email').value; | |
if (!email) { | |
alert('Please enter an email address'); | |
return; | |
} | |
message += `\n\nSent to: ${email}`; | |
} | |
const userMessage = document.getElementById('share-message').value; | |
if (userMessage) { | |
message += `\n\nMessage: ${userMessage}`; | |
} | |
alert(`Task shared via ${method}!\n\n${message}`); | |
hideModal('share-task-modal'); | |
// In a real app, we would actually send the email or Slack message here | |
} | |
function assignTask(taskName) { | |
alert(`Task "${taskName}" assigned to a team member!`); | |
// In a real app, we would have a proper assignment flow | |
} | |
function sendTask(taskName) { | |
alert(`Task "${taskName}" sent to external tool!`); | |
// In a real app, we would integrate with actual tools | |
} | |
function showAllTasks(type) { | |
alert(`Showing all ${type} tasks`); | |
// In a real app, we would navigate to a task list view | |
} | |
// Profile functions | |
function saveProfile() { | |
appState.user.name = document.getElementById('profile-name').value; | |
appState.user.email = document.getElementById('profile-email').value; | |
appState.user.apiKey = document.getElementById('api-key').value; | |
appState.user.streak = parseInt(document.getElementById('profile-streak').value); | |
appState.user.level = parseInt(document.getElementById('profile-level').value); | |
appState.user.xp = parseInt(document.getElementById('profile-xp').value); | |
appState.user.maxXp = parseInt(document.getElementById('profile-max-xp').value); | |
updateUIFromState(); | |
saveStateToLocalStorage(); | |
hideModal('profile-modal'); | |
} | |
// AI functions | |
function showAIChatModal() { | |
// Render chat messages | |
const chatContainer = document.getElementById('chat-messages'); | |
chatContainer.innerHTML = ''; | |
appState.chatMessages.forEach(message => { | |
const messageDiv = document.createElement('div'); | |
messageDiv.className = `chat-message ${message.sender === 'user' ? 'user-message' : 'ai-message'}`; | |
messageDiv.textContent = message.content; | |
chatContainer.appendChild(messageDiv); | |
}); | |
showModal('ai-chat-modal'); | |
document.getElementById('chat-input').focus(); | |
} | |
function sendChatMessage() { | |
const input = document.getElementById('chat-input'); | |
const message = input.value.trim(); | |
if (!message) return; | |
// Add user message to chat | |
appState.chatMessages.push({ | |
sender: 'user', | |
content: message | |
}); | |
// Clear input | |
input.value = ''; | |
// Show "AI is typing" indicator | |
const chatContainer = document.getElementById('chat-messages'); | |
const typingIndicator = document.createElement('div'); | |
typingIndicator.className = 'chat-message ai-message'; | |
typingIndicator.textContent = 'AI is typing...'; | |
chatContainer.appendChild(typingIndicator); | |
chatContainer.scrollTop = chatContainer.scrollHeight; | |
// Process message with AI (simulated for demo) | |
setTimeout(() => { | |
// Remove typing indicator | |
chatContainer.removeChild(typingIndicator); | |
// Add AI response | |
const aiResponse = getAIResponse(message); | |
appState.chatMessages.push({ | |
sender: 'ai', | |
content: aiResponse | |
}); | |
// Update chat UI | |
const messageDiv = document.createElement('div'); | |
messageDiv.className = 'chat-message ai-message'; | |
messageDiv.textContent = aiResponse; | |
chatContainer.appendChild(messageDiv); | |
chatContainer.scrollTop = chatContainer.scrollHeight; | |
saveStateToLocalStorage(); | |
}, 1000); | |
} | |
function getAIResponse(message) { | |
// In a real app, this would call the Deepseek API | |
// For demo purposes, we're using simple pattern matching | |
// Check if API key is set | |
if (!appState.user.apiKey) { | |
return "Please set your Deepseek API key in your profile to use the full AI capabilities. For now, I can only provide basic responses."; | |
} | |
// Simple pattern matching for demo purposes | |
const lowerMessage = message.toLowerCase(); | |
if (lowerMessage.includes('hello') || lowerMessage.includes('hi')) { | |
return "Hello! How can I assist you with your business goals today?"; | |
} else if (lowerMessage.includes('goal') || lowerMessage.includes('target')) { | |
return `Based on your current goal to ${appState.goal.title}, I recommend focusing on high-impact activities that directly contribute to this outcome. Have you considered optimizing your conversion funnel?`; | |
} else if (lowerMessage.includes('task') || lowerMessage.includes('prioritize')) { | |
return "For maximum impact, prioritize tasks that directly affect your revenue or customer acquisition. Delegate or automate lower-impact tasks when possible."; | |
} else if (lowerMessage.includes('help') || lowerMessage.includes('advice')) { | |
return "I'd be happy to help! Could you provide more details about what you're working on? For example, are you looking for marketing, product, or operational advice?"; | |
} else if (lowerMessage.includes('mrr') || lowerMessage.includes('revenue')) { | |
return "To increase your MRR, focus on: 1) Improving conversion rates, 2) Reducing churn, and 3) Expanding your offerings. Would you like me to generate specific tactics for any of these areas?"; | |
} else { | |
return "I'm here to help you achieve your business goals. Could you clarify or provide more details about your question?"; | |
} | |
} | |
function updateAIRecommendation() { | |
// In a real app, this would call the Deepseek API with the current goal | |
// For demo, we're using a simple template | |
document.getElementById('ai-recommendation').textContent = | |
`"Based on your current progress toward ${appState.goal.title}, I recommend focusing on high-leverage activities that will move you from ${appState.goal.current} to ${appState.goal.target}."`; | |
} | |
// Handle Enter key in chat | |
document.getElementById('chat-input').addEventListener('keypress', function(e) { | |
if (e.key === 'Enter') { | |
sendChatMessage(); | |
} | |
}); | |
</script> | |
<p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=JayStormX8/sky-ai-goals-game" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body> | |
</html> |