kasramojallal commited on
Commit
9cb9419
·
verified ·
1 Parent(s): 222ca64

Add 2 files

Browse files
Files changed (2) hide show
  1. index.html +684 -51
  2. prompts.txt +2 -0
index.html CHANGED
@@ -3,9 +3,11 @@
3
  <head>
4
  <meta charset="UTF-8">
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
- <title>Job Application Tracker</title>
7
  <script src="https://cdn.tailwindcss.com"></script>
8
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
 
 
9
  <style>
10
  .fade-in {
11
  animation: fadeIn 0.3s ease-in-out;
@@ -15,20 +17,37 @@
15
  to { opacity: 1; transform: translateY(0); }
16
  }
17
  .pulse {
18
- animation: pulse 2s infinite;
19
  }
20
  @keyframes pulse {
21
  0% { transform: scale(1); }
22
  50% { transform: scale(1.05); }
23
  100% { transform: scale(1); }
24
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
25
  </style>
26
  </head>
27
  <body class="bg-gradient-to-br from-blue-50 to-indigo-100 min-h-screen">
28
- <div class="container mx-auto px-4 py-8 max-w-3xl">
29
  <header class="text-center mb-8">
30
- <h1 class="text-4xl font-bold text-indigo-800 mb-2">Job Application Tracker</h1>
31
- <p class="text-indigo-600">Keep track of your job search progress</p>
32
  </header>
33
 
34
  <div class="bg-white rounded-xl shadow-lg p-6 mb-8">
@@ -36,14 +55,54 @@
36
  <div class="text-center md:text-left mb-4 md:mb-0">
37
  <h2 class="text-2xl font-semibold text-gray-800">Today's Applications</h2>
38
  <p class="text-gray-500" id="today-date">Loading date...</p>
 
 
 
 
 
 
39
  </div>
40
  <div class="flex items-center space-x-4">
41
- <div class="bg-indigo-100 rounded-full p-4">
42
- <span class="text-3xl font-bold text-indigo-800" id="today-count">0</span>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
43
  </div>
44
- <button id="add-btn" class="bg-indigo-600 hover:bg-indigo-700 text-white rounded-full w-14 h-14 flex items-center justify-center shadow-md transition-all transform hover:scale-105">
45
- <i class="fas fa-plus text-2xl"></i>
46
- </button>
47
  </div>
48
  </div>
49
 
@@ -52,29 +111,140 @@
52
  <h3 class="font-medium text-gray-700">Total Applications</h3>
53
  <span class="text-xl font-bold text-indigo-800" id="total-count">0</span>
54
  </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
55
  </div>
56
  </div>
57
 
58
  <div class="bg-white rounded-xl shadow-lg p-6">
59
  <div class="flex justify-between items-center mb-4">
60
  <h2 class="text-2xl font-semibold text-gray-800">Application History</h2>
61
- <button id="clear-btn" class="text-red-500 hover:text-red-700 flex items-center">
62
- <i class="fas fa-trash-alt mr-1"></i>
63
- <span>Clear All</span>
64
- </button>
 
 
65
  </div>
66
 
67
  <div id="history-list" class="space-y-3">
68
  <div class="text-center py-8 text-gray-400" id="empty-state">
69
  <i class="fas fa-clipboard-list text-4xl mb-2"></i>
70
  <p>No applications recorded yet</p>
 
 
 
71
  </div>
72
  <!-- History items will be added here dynamically -->
73
  </div>
74
  </div>
75
 
76
  <div class="mt-6 text-center text-sm text-gray-500">
77
- <p>Keep applying! Every application brings you closer to your dream job.</p>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
78
  </div>
79
  </div>
80
 
@@ -82,22 +252,153 @@
82
  document.addEventListener('DOMContentLoaded', function() {
83
  // Get elements
84
  const addBtn = document.getElementById('add-btn');
 
 
85
  const todayCountEl = document.getElementById('today-count');
86
  const totalCountEl = document.getElementById('total-count');
87
  const historyList = document.getElementById('history-list');
88
  const emptyState = document.getElementById('empty-state');
89
- const clearBtn = document.getElementById('clear-btn');
90
  const todayDateEl = document.getElementById('today-date');
 
 
 
91
 
92
- // Format today's date
93
- const today = new Date();
94
- const formattedDate = today.toLocaleDateString('en-US', {
95
- weekday: 'long',
96
- year: 'numeric',
97
- month: 'long',
98
- day: 'numeric'
99
- });
100
- todayDateEl.textContent = formattedDate;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
101
 
102
  // Initialize data from localStorage or create new
103
  let appData = JSON.parse(localStorage.getItem('jobAppData')) || {
@@ -106,11 +407,10 @@
106
  };
107
 
108
  // Check if today's date exists in history
109
- const todayKey = today.toISOString().split('T')[0];
110
  let todayEntry = appData.history.find(entry => entry.date === todayKey);
111
 
112
  if (!todayEntry) {
113
- todayEntry = { date: todayKey, count: 0 };
114
  appData.history.unshift(todayEntry);
115
  saveData();
116
  }
@@ -118,6 +418,24 @@
118
  // Update UI
119
  updateCounts();
120
  renderHistory();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
121
 
122
  // Add button click handler
123
  addBtn.addEventListener('click', function() {
@@ -126,26 +444,204 @@
126
 
127
  // Add animation effect
128
  this.classList.add('pulse');
129
- setTimeout(() => this.classList.remove('pulse'), 2000);
130
 
131
  saveData();
132
  updateCounts();
133
  renderHistory();
 
134
  });
135
 
136
- // Clear button click handler
137
- clearBtn.addEventListener('click', function() {
138
- if (confirm('Are you sure you want to clear all application history?')) {
139
- appData = {
140
- total: 0,
141
- history: []
142
- };
143
- todayEntry = { date: todayKey, count: 0 };
144
- appData.history.unshift(todayEntry);
145
 
146
  saveData();
147
  updateCounts();
148
  renderHistory();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
149
  }
150
  });
151
 
@@ -154,6 +650,14 @@
154
  todayCountEl.textContent = todayEntry.count;
155
  totalCountEl.textContent = appData.total;
156
 
 
 
 
 
 
 
 
 
157
  // Add animation when count changes
158
  todayCountEl.classList.add('fade-in');
159
  totalCountEl.classList.add('fade-in');
@@ -173,42 +677,171 @@
173
  emptyState.style.display = 'none';
174
  historyList.innerHTML = '';
175
 
176
- appData.history.forEach(entry => {
 
 
 
177
  if (entry.count === 0 && entry.date === todayKey) return;
178
 
179
  const entryDate = new Date(entry.date);
180
  const isToday = entry.date === todayKey;
181
 
182
- const formattedEntryDate = entryDate.toLocaleDateString('en-US', {
183
- weekday: 'short',
184
- month: 'short',
185
- day: 'numeric',
186
- year: 'numeric'
187
- });
188
 
189
  const historyItem = document.createElement('div');
190
- historyItem.className = 'flex justify-between items-center p-3 bg-gray-50 rounded-lg fade-in';
191
  if (isToday) {
192
- historyItem.classList.add('border-l-4', 'border-indigo-500');
193
  }
194
 
195
  historyItem.innerHTML = `
196
  <div class="flex items-center">
197
- <div class="w-10 h-10 rounded-full bg-indigo-100 flex items-center justify-center mr-3">
198
- <i class="fas fa-briefcase text-indigo-600"></i>
199
  </div>
200
  <div>
201
- <p class="font-medium ${isToday ? 'text-indigo-800' : 'text-gray-800'}">${formattedEntryDate}</p>
202
- <p class="text-xs text-gray-500">${isToday ? 'Today' : ''}</p>
203
  </div>
204
  </div>
205
- <span class="text-lg font-bold ${isToday ? 'text-indigo-800' : 'text-gray-700'}">${entry.count}</span>
 
 
206
  `;
207
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
208
  historyList.appendChild(historyItem);
209
  });
210
  }
211
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
212
  // Save data to localStorage
213
  function saveData() {
214
  localStorage.setItem('jobAppData', JSON.stringify(appData));
 
3
  <head>
4
  <meta charset="UTF-8">
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Job Application Tracker Pro</title>
7
  <script src="https://cdn.tailwindcss.com"></script>
8
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
9
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.1/moment.min.js"></script>
10
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/moment-timezone/0.5.34/moment-timezone-with-data.min.js"></script>
11
  <style>
12
  .fade-in {
13
  animation: fadeIn 0.3s ease-in-out;
 
17
  to { opacity: 1; transform: translateY(0); }
18
  }
19
  .pulse {
20
+ animation: pulse 1s infinite;
21
  }
22
  @keyframes pulse {
23
  0% { transform: scale(1); }
24
  50% { transform: scale(1.05); }
25
  100% { transform: scale(1); }
26
  }
27
+ .modal {
28
+ transition: opacity 0.3s ease;
29
+ }
30
+ .modal-overlay {
31
+ background-color: rgba(0, 0, 0, 0.5);
32
+ }
33
+ .chart-bar {
34
+ transition: height 0.5s ease-out;
35
+ }
36
+ .progress-ring__circle {
37
+ transition: stroke-dashoffset 0.5s ease-out;
38
+ transform: rotate(-90deg);
39
+ transform-origin: 50% 50%;
40
+ }
41
+ .glow {
42
+ box-shadow: 0 0 15px rgba(99, 102, 241, 0.5);
43
+ }
44
  </style>
45
  </head>
46
  <body class="bg-gradient-to-br from-blue-50 to-indigo-100 min-h-screen">
47
+ <div class="container mx-auto px-4 py-8 max-w-4xl">
48
  <header class="text-center mb-8">
49
+ <h1 class="text-4xl font-bold text-indigo-800 mb-2">Job Application Tracker Pro</h1>
50
+ <p class="text-indigo-600">Track, analyze, and optimize your job search</p>
51
  </header>
52
 
53
  <div class="bg-white rounded-xl shadow-lg p-6 mb-8">
 
55
  <div class="text-center md:text-left mb-4 md:mb-0">
56
  <h2 class="text-2xl font-semibold text-gray-800">Today's Applications</h2>
57
  <p class="text-gray-500" id="today-date">Loading date...</p>
58
+ <div class="mt-2 flex items-center justify-center md:justify-start">
59
+ <span class="text-xs bg-indigo-100 text-indigo-800 px-2 py-1 rounded-full flex items-center">
60
+ <i class="fas fa-clock mr-1 text-xs"></i>
61
+ <span id="timezone-display">Detecting timezone...</span>
62
+ </span>
63
+ </div>
64
  </div>
65
  <div class="flex items-center space-x-4">
66
+ <div class="relative">
67
+ <svg class="w-24 h-24">
68
+ <circle
69
+ class="text-gray-200"
70
+ stroke-width="8"
71
+ stroke="currentColor"
72
+ fill="transparent"
73
+ r="36"
74
+ cx="40"
75
+ cy="40"
76
+ />
77
+ <circle
78
+ class="progress-ring__circle text-indigo-600"
79
+ stroke-width="8"
80
+ stroke-linecap="round"
81
+ stroke="currentColor"
82
+ fill="transparent"
83
+ r="36"
84
+ cx="40"
85
+ cy="40"
86
+ id="progress-ring"
87
+ />
88
+ </svg>
89
+ <div class="absolute inset-0 flex items-center justify-center">
90
+ <span class="text-2xl font-bold text-indigo-800" id="today-count">0</span>
91
+ </div>
92
+ </div>
93
+ <div class="flex flex-col space-y-2">
94
+ <div class="flex space-x-2">
95
+ <button id="decrease-btn" class="bg-red-500 hover:bg-red-600 text-white rounded-full w-12 h-12 flex items-center justify-center shadow-md transition-all transform hover:scale-105">
96
+ <i class="fas fa-minus text-lg"></i>
97
+ </button>
98
+ <button id="add-btn" class="bg-indigo-600 hover:bg-indigo-700 text-white rounded-full w-12 h-12 flex items-center justify-center shadow-md transition-all transform hover:scale-105">
99
+ <i class="fas fa-plus text-lg"></i>
100
+ </button>
101
+ </div>
102
+ <button id="add-custom-btn" class="bg-indigo-100 hover:bg-indigo-200 text-indigo-700 rounded-full w-full h-8 flex items-center justify-center shadow-md text-sm transition-all">
103
+ <i class="fas fa-calendar-day mr-1"></i> Custom Date
104
+ </button>
105
  </div>
 
 
 
106
  </div>
107
  </div>
108
 
 
111
  <h3 class="font-medium text-gray-700">Total Applications</h3>
112
  <span class="text-xl font-bold text-indigo-800" id="total-count">0</span>
113
  </div>
114
+ <div class="w-full bg-gray-200 rounded-full h-2.5">
115
+ <div id="total-progress" class="bg-indigo-600 h-2.5 rounded-full" style="width: 0%"></div>
116
+ </div>
117
+ </div>
118
+ </div>
119
+
120
+ <div class="grid grid-cols-1 md:grid-cols-2 gap-6 mb-8">
121
+ <div class="bg-white rounded-xl shadow-lg p-6">
122
+ <h2 class="text-xl font-semibold text-gray-800 mb-4">Weekly Overview</h2>
123
+ <div class="flex justify-between items-end h-40 mt-6">
124
+ <!-- Weekly chart bars will be added here -->
125
+ </div>
126
+ </div>
127
+ <div class="bg-white rounded-xl shadow-lg p-6">
128
+ <h2 class="text-xl font-semibold text-gray-800 mb-4">Monthly Progress</h2>
129
+ <div class="flex justify-center">
130
+ <div id="monthly-chart" class="w-full h-40">
131
+ <!-- Monthly chart will be added here -->
132
+ </div>
133
+ </div>
134
  </div>
135
  </div>
136
 
137
  <div class="bg-white rounded-xl shadow-lg p-6">
138
  <div class="flex justify-between items-center mb-4">
139
  <h2 class="text-2xl font-semibold text-gray-800">Application History</h2>
140
+ <div class="flex space-x-2">
141
+ <button id="settings-btn" class="text-indigo-600 hover:text-indigo-800 flex items-center">
142
+ <i class="fas fa-cog mr-1"></i>
143
+ <span>Settings</span>
144
+ </button>
145
+ </div>
146
  </div>
147
 
148
  <div id="history-list" class="space-y-3">
149
  <div class="text-center py-8 text-gray-400" id="empty-state">
150
  <i class="fas fa-clipboard-list text-4xl mb-2"></i>
151
  <p>No applications recorded yet</p>
152
+ <button id="get-started-btn" class="mt-4 px-4 py-2 bg-indigo-600 hover:bg-indigo-700 text-white rounded-md">
153
+ Add Your First Application
154
+ </button>
155
  </div>
156
  <!-- History items will be added here dynamically -->
157
  </div>
158
  </div>
159
 
160
  <div class="mt-6 text-center text-sm text-gray-500">
161
+ <p>Every application is a step closer to your dream job. Keep going!</p>
162
+ </div>
163
+ </div>
164
+
165
+ <!-- Modal for custom date entry -->
166
+ <div id="date-modal" class="fixed inset-0 flex items-center justify-center z-50 modal opacity-0 pointer-events-none">
167
+ <div class="modal-overlay absolute inset-0"></div>
168
+ <div class="bg-white rounded-xl shadow-xl p-6 z-10 w-full max-w-md transform transition-all scale-95">
169
+ <div class="flex justify-between items-center mb-4">
170
+ <h3 class="text-xl font-semibold text-gray-800">Add/Edit Applications</h3>
171
+ <button id="close-modal" class="text-gray-500 hover:text-gray-700">
172
+ <i class="fas fa-times"></i>
173
+ </button>
174
+ </div>
175
+ <div class="mb-4">
176
+ <label for="custom-date" class="block text-sm font-medium text-gray-700 mb-1">Select Date</label>
177
+ <input type="date" id="custom-date" class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-indigo-500">
178
+ </div>
179
+ <div class="mb-4">
180
+ <label for="custom-count" class="block text-sm font-medium text-gray-700 mb-1">Number of Applications</label>
181
+ <div class="flex items-center">
182
+ <button id="decrease-custom" class="bg-gray-200 hover:bg-gray-300 text-gray-800 rounded-l-md w-10 h-10 flex items-center justify-center">
183
+ <i class="fas fa-minus"></i>
184
+ </button>
185
+ <input type="number" id="custom-count" min="0" value="1" class="w-full px-3 py-2 border-t border-b border-gray-300 text-center focus:outline-none">
186
+ <button id="increase-custom" class="bg-gray-200 hover:bg-gray-300 text-gray-800 rounded-r-md w-10 h-10 flex items-center justify-center">
187
+ <i class="fas fa-plus"></i>
188
+ </button>
189
+ </div>
190
+ </div>
191
+ <div class="mb-4">
192
+ <label for="custom-notes" class="block text-sm font-medium text-gray-700 mb-1">Notes (optional)</label>
193
+ <textarea id="custom-notes" rows="2" class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-indigo-500" placeholder="Add any notes about these applications..."></textarea>
194
+ </div>
195
+ <div class="flex justify-end space-x-3">
196
+ <button id="delete-entry" class="px-4 py-2 text-red-600 hover:text-red-800 hidden">
197
+ <i class="fas fa-trash mr-1"></i> Delete
198
+ </button>
199
+ <button id="cancel-modal" class="px-4 py-2 text-gray-600 hover:text-gray-800">
200
+ Cancel
201
+ </button>
202
+ <button id="save-custom" class="px-4 py-2 bg-indigo-600 hover:bg-indigo-700 text-white rounded-md">
203
+ Save
204
+ </button>
205
+ </div>
206
+ </div>
207
+ </div>
208
+
209
+ <!-- Settings Modal -->
210
+ <div id="settings-modal" class="fixed inset-0 flex items-center justify-center z-50 modal opacity-0 pointer-events-none">
211
+ <div class="modal-overlay absolute inset-0"></div>
212
+ <div class="bg-white rounded-xl shadow-xl p-6 z-10 w-full max-w-md transform transition-all scale-95">
213
+ <div class="flex justify-between items-center mb-4">
214
+ <h3 class="text-xl font-semibold text-gray-800">Settings</h3>
215
+ <button id="close-settings" class="text-gray-500 hover:text-gray-700">
216
+ <i class="fas fa-times"></i>
217
+ </button>
218
+ </div>
219
+ <div class="mb-4">
220
+ <label for="timezone-select" class="block text-sm font-medium text-gray-700 mb-1">Timezone</label>
221
+ <select id="timezone-select" class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-indigo-500">
222
+ <option value="auto">Auto-detect</option>
223
+ <!-- Timezone options will be added dynamically -->
224
+ </select>
225
+ </div>
226
+ <div class="mb-4">
227
+ <label for="daily-goal" class="block text-sm font-medium text-gray-700 mb-1">Daily Goal</label>
228
+ <input type="number" id="daily-goal" min="1" value="5" class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-indigo-500">
229
+ </div>
230
+ <div class="mb-4">
231
+ <label class="block text-sm font-medium text-gray-700 mb-1">Visual Theme</label>
232
+ <div class="flex space-x-2">
233
+ <button data-theme="indigo" class="theme-btn w-8 h-8 rounded-full bg-indigo-600 border-2 border-indigo-800"></button>
234
+ <button data-theme="emerald" class="theme-btn w-8 h-8 rounded-full bg-emerald-600 border-2 border-transparent"></button>
235
+ <button data-theme="rose" class="theme-btn w-8 h-8 rounded-full bg-rose-600 border-2 border-transparent"></button>
236
+ <button data-theme="violet" class="theme-btn w-8 h-8 rounded-full bg-violet-600 border-2 border-transparent"></button>
237
+ <button data-theme="sky" class="theme-btn w-8 h-8 rounded-full bg-sky-600 border-2 border-transparent"></button>
238
+ </div>
239
+ </div>
240
+ <div class="flex justify-end space-x-3">
241
+ <button id="cancel-settings" class="px-4 py-2 text-gray-600 hover:text-gray-800">
242
+ Cancel
243
+ </button>
244
+ <button id="save-settings" class="px-4 py-2 bg-indigo-600 hover:bg-indigo-700 text-white rounded-md">
245
+ Save Settings
246
+ </button>
247
+ </div>
248
  </div>
249
  </div>
250
 
 
252
  document.addEventListener('DOMContentLoaded', function() {
253
  // Get elements
254
  const addBtn = document.getElementById('add-btn');
255
+ const decreaseBtn = document.getElementById('decrease-btn');
256
+ const addCustomBtn = document.getElementById('add-custom-btn');
257
  const todayCountEl = document.getElementById('today-count');
258
  const totalCountEl = document.getElementById('total-count');
259
  const historyList = document.getElementById('history-list');
260
  const emptyState = document.getElementById('empty-state');
261
+ const getStartedBtn = document.getElementById('get-started-btn');
262
  const todayDateEl = document.getElementById('today-date');
263
+ const timezoneDisplay = document.getElementById('timezone-display');
264
+ const progressRing = document.getElementById('progress-ring');
265
+ const totalProgress = document.getElementById('total-progress');
266
 
267
+ // Modal elements
268
+ const dateModal = document.getElementById('date-modal');
269
+ const closeModal = document.getElementById('close-modal');
270
+ const cancelModal = document.getElementById('cancel-modal');
271
+ const saveCustom = document.getElementById('save-custom');
272
+ const customDate = document.getElementById('custom-date');
273
+ const customCount = document.getElementById('custom-count');
274
+ const customNotes = document.getElementById('custom-notes');
275
+ const decreaseCustom = document.getElementById('decrease-custom');
276
+ const increaseCustom = document.getElementById('increase-custom');
277
+ const deleteEntryBtn = document.getElementById('delete-entry');
278
+
279
+ // Settings modal elements
280
+ const settingsModal = document.getElementById('settings-modal');
281
+ const settingsBtn = document.getElementById('settings-btn');
282
+ const closeSettings = document.getElementById('close-settings');
283
+ const cancelSettings = document.getElementById('cancel-settings');
284
+ const saveSettings = document.getElementById('save-settings');
285
+ const timezoneSelect = document.getElementById('timezone-select');
286
+ const dailyGoalInput = document.getElementById('daily-goal');
287
+ const themeButtons = document.querySelectorAll('.theme-btn');
288
+
289
+ // Initialize with default settings
290
+ let userSettings = JSON.parse(localStorage.getItem('jobAppSettings')) || {
291
+ timezone: 'auto',
292
+ dailyGoal: 5,
293
+ theme: 'indigo'
294
+ };
295
+
296
+ // Apply theme
297
+ function applyTheme(theme) {
298
+ const colors = {
299
+ indigo: { primary: 'indigo', secondary: 'blue' },
300
+ emerald: { primary: 'emerald', secondary: 'green' },
301
+ rose: { primary: 'rose', secondary: 'pink' },
302
+ violet: { primary: 'violet', secondary: 'purple' },
303
+ sky: { primary: 'sky', secondary: 'cyan' }
304
+ };
305
+
306
+ const colorSet = colors[theme] || colors.indigo;
307
+
308
+ // Update all elements with theme classes
309
+ document.querySelectorAll('[class*="bg-indigo-"]').forEach(el => {
310
+ el.className = el.className.replace(/bg-indigo-\d+/g, `bg-${colorSet.primary}-600`);
311
+ });
312
+
313
+ document.querySelectorAll('[class*="text-indigo-"]').forEach(el => {
314
+ el.className = el.className.replace(/text-indigo-\d+/g, `text-${colorSet.primary}-800`);
315
+ });
316
+
317
+ document.querySelectorAll('[class*="border-indigo-"]').forEach(el => {
318
+ el.className = el.className.replace(/border-indigo-\d+/g, `border-${colorSet.primary}-800`);
319
+ });
320
+
321
+ document.querySelectorAll('[class*="from-blue-"]').forEach(el => {
322
+ el.className = el.className.replace(/from-blue-\d+/g, `from-${colorSet.secondary}-50`);
323
+ });
324
+
325
+ document.querySelectorAll('[class*="to-indigo-"]').forEach(el => {
326
+ el.className = el.className.replace(/to-indigo-\d+/g, `to-${colorSet.primary}-100`);
327
+ });
328
+
329
+ // Update progress bar
330
+ if (totalProgress) {
331
+ totalProgress.className = totalProgress.className.replace(/bg-indigo-\d+/g, `bg-${colorSet.primary}-600`);
332
+ }
333
+
334
+ // Update theme buttons
335
+ themeButtons.forEach(btn => {
336
+ if (btn.dataset.theme === theme) {
337
+ btn.classList.replace('border-transparent', `border-${colorSet.primary}-800`);
338
+ } else {
339
+ btn.classList.replace(`border-${colorSet.primary}-800`, 'border-transparent');
340
+ }
341
+ });
342
+ }
343
+
344
+ // Apply saved theme
345
+ applyTheme(userSettings.theme);
346
+
347
+ // Populate timezone dropdown
348
+ function populateTimezones() {
349
+ const timezones = moment.tz.names();
350
+ timezoneSelect.innerHTML = '<option value="auto">Auto-detect</option>';
351
+
352
+ timezones.forEach(tz => {
353
+ const option = document.createElement('option');
354
+ option.value = tz;
355
+ option.textContent = tz;
356
+ if (tz === userSettings.timezone && userSettings.timezone !== 'auto') {
357
+ option.selected = true;
358
+ }
359
+ timezoneSelect.appendChild(option);
360
+ });
361
+ }
362
+
363
+ populateTimezones();
364
+
365
+ // Get current date based on user's timezone
366
+ function getCurrentDate() {
367
+ if (userSettings.timezone === 'auto') {
368
+ return moment().format('YYYY-MM-DD');
369
+ } else {
370
+ return moment().tz(userSettings.timezone).format('YYYY-MM-DD');
371
+ }
372
+ }
373
+
374
+ // Format date for display
375
+ function formatDateDisplay(dateStr) {
376
+ if (userSettings.timezone === 'auto') {
377
+ return moment(dateStr).format('dddd, MMMM D, YYYY');
378
+ } else {
379
+ return moment.tz(dateStr, userSettings.timezone).format('dddd, MMMM D, YYYY');
380
+ }
381
+ }
382
+
383
+ // Set today's date
384
+ const todayKey = getCurrentDate();
385
+ todayDateEl.textContent = formatDateDisplay(todayKey);
386
+
387
+ // Display timezone
388
+ function displayTimezone() {
389
+ if (userSettings.timezone === 'auto') {
390
+ const detectedTz = moment.tz.guess();
391
+ timezoneDisplay.textContent = detectedTz;
392
+ } else {
393
+ timezoneDisplay.textContent = userSettings.timezone;
394
+ }
395
+ }
396
+
397
+ displayTimezone();
398
+
399
+ // Set default date in modal to today
400
+ customDate.value = todayKey;
401
+ dailyGoalInput.value = userSettings.dailyGoal;
402
 
403
  // Initialize data from localStorage or create new
404
  let appData = JSON.parse(localStorage.getItem('jobAppData')) || {
 
407
  };
408
 
409
  // Check if today's date exists in history
 
410
  let todayEntry = appData.history.find(entry => entry.date === todayKey);
411
 
412
  if (!todayEntry) {
413
+ todayEntry = { date: todayKey, count: 0, notes: '' };
414
  appData.history.unshift(todayEntry);
415
  saveData();
416
  }
 
418
  // Update UI
419
  updateCounts();
420
  renderHistory();
421
+ renderCharts();
422
+
423
+ // Update progress ring
424
+ function updateProgressRing() {
425
+ const radius = 36;
426
+ const circumference = radius * 2 * Math.PI;
427
+ const progress = (todayEntry.count / userSettings.dailyGoal) * 100;
428
+ const offset = circumference - (progress / 100) * circumference;
429
+
430
+ progressRing.style.strokeDasharray = `${circumference} ${circumference}`;
431
+ progressRing.style.strokeDashoffset = offset;
432
+
433
+ if (progress >= 100) {
434
+ progressRing.classList.add('glow');
435
+ } else {
436
+ progressRing.classList.remove('glow');
437
+ }
438
+ }
439
 
440
  // Add button click handler
441
  addBtn.addEventListener('click', function() {
 
444
 
445
  // Add animation effect
446
  this.classList.add('pulse');
447
+ setTimeout(() => this.classList.remove('pulse'), 1000);
448
 
449
  saveData();
450
  updateCounts();
451
  renderHistory();
452
+ renderCharts();
453
  });
454
 
455
+ // Decrease button click handler
456
+ decreaseBtn.addEventListener('click', function() {
457
+ if (todayEntry.count > 0) {
458
+ todayEntry.count--;
459
+ appData.total--;
 
 
 
 
460
 
461
  saveData();
462
  updateCounts();
463
  renderHistory();
464
+ renderCharts();
465
+ }
466
+ });
467
+
468
+ // Add custom date button click handler
469
+ addCustomBtn.addEventListener('click', function() {
470
+ // Reset modal values
471
+ customDate.value = todayKey;
472
+ customCount.value = 1;
473
+ customNotes.value = '';
474
+ deleteEntryBtn.classList.add('hidden');
475
+
476
+ // Show modal
477
+ openModal();
478
+ });
479
+
480
+ // Get started button
481
+ getStartedBtn.addEventListener('click', function() {
482
+ addBtn.click();
483
+ });
484
+
485
+ // Modal open/close handlers
486
+ function openModal() {
487
+ dateModal.classList.remove('opacity-0', 'pointer-events-none');
488
+ dateModal.classList.add('opacity-100', 'pointer-events-auto');
489
+ setTimeout(() => {
490
+ dateModal.querySelector('.z-10').classList.remove('scale-95');
491
+ dateModal.querySelector('.z-10').classList.add('scale-100');
492
+ }, 10);
493
+ }
494
+
495
+ function closeModalHandler() {
496
+ dateModal.querySelector('.z-10').classList.remove('scale-100');
497
+ dateModal.querySelector('.z-10').classList.add('scale-95');
498
+ setTimeout(() => {
499
+ dateModal.classList.remove('opacity-100', 'pointer-events-auto');
500
+ dateModal.classList.add('opacity-0', 'pointer-events-none');
501
+ }, 200);
502
+ }
503
+
504
+ closeModal.addEventListener('click', closeModalHandler);
505
+ cancelModal.addEventListener('click', closeModalHandler);
506
+
507
+ // Settings modal handlers
508
+ function openSettingsModal() {
509
+ settingsModal.classList.remove('opacity-0', 'pointer-events-none');
510
+ settingsModal.classList.add('opacity-100', 'pointer-events-auto');
511
+ setTimeout(() => {
512
+ settingsModal.querySelector('.z-10').classList.remove('scale-95');
513
+ settingsModal.querySelector('.z-10').classList.add('scale-100');
514
+ }, 10);
515
+ }
516
+
517
+ function closeSettingsHandler() {
518
+ settingsModal.querySelector('.z-10').classList.remove('scale-100');
519
+ settingsModal.querySelector('.z-10').classList.add('scale-95');
520
+ setTimeout(() => {
521
+ settingsModal.classList.remove('opacity-100', 'pointer-events-auto');
522
+ settingsModal.classList.add('opacity-0', 'pointer-events-none');
523
+ }, 200);
524
+ }
525
+
526
+ settingsBtn.addEventListener('click', openSettingsModal);
527
+ closeSettings.addEventListener('click', closeSettingsHandler);
528
+ cancelSettings.addEventListener('click', closeSettingsHandler);
529
+
530
+ // Save settings
531
+ saveSettings.addEventListener('click', function() {
532
+ userSettings.timezone = timezoneSelect.value;
533
+ userSettings.dailyGoal = parseInt(dailyGoalInput.value);
534
+
535
+ // Find and apply selected theme
536
+ themeButtons.forEach(btn => {
537
+ if (btn.classList.contains('border-indigo-800') ||
538
+ btn.classList.contains('border-emerald-800') ||
539
+ btn.classList.contains('border-rose-800') ||
540
+ btn.classList.contains('border-violet-800') ||
541
+ btn.classList.contains('border-sky-800')) {
542
+ userSettings.theme = btn.dataset.theme;
543
+ }
544
+ });
545
+
546
+ localStorage.setItem('jobAppSettings', JSON.stringify(userSettings));
547
+ applyTheme(userSettings.theme);
548
+ displayTimezone();
549
+ closeSettingsHandler();
550
+
551
+ // Update today's date if timezone changed
552
+ const newTodayKey = getCurrentDate();
553
+ if (newTodayKey !== todayKey) {
554
+ // Need to handle timezone change - this would require more complex logic
555
+ // For now, we'll just refresh the display
556
+ location.reload();
557
+ }
558
+ });
559
+
560
+ // Theme selection
561
+ themeButtons.forEach(btn => {
562
+ btn.addEventListener('click', function() {
563
+ themeButtons.forEach(b => {
564
+ b.classList.replace(/border-\w+-800/g, 'border-transparent');
565
+ });
566
+
567
+ const theme = this.dataset.theme;
568
+ const colorSet = {
569
+ indigo: 'indigo',
570
+ emerald: 'emerald',
571
+ rose: 'rose',
572
+ violet: 'violet',
573
+ sky: 'sky'
574
+ }[theme];
575
+
576
+ this.classList.replace('border-transparent', `border-${colorSet}-800`);
577
+ });
578
+ });
579
+
580
+ // Custom count controls
581
+ decreaseCustom.addEventListener('click', function() {
582
+ if (customCount.value > 0) {
583
+ customCount.value--;
584
+ }
585
+ });
586
+
587
+ increaseCustom.addEventListener('click', function() {
588
+ customCount.value++;
589
+ });
590
+
591
+ // Save custom entry
592
+ saveCustom.addEventListener('click', function() {
593
+ const selectedDate = customDate.value;
594
+ const count = parseInt(customCount.value);
595
+ const notes = customNotes.value.trim();
596
+
597
+ if (isNaN(count) || count < 0) {
598
+ alert('Please enter a valid number of applications');
599
+ return;
600
+ }
601
+
602
+ // Find or create entry for selected date
603
+ let entry = appData.history.find(entry => entry.date === selectedDate);
604
+
605
+ if (entry) {
606
+ // Calculate the difference to update total correctly
607
+ const diff = count - (entry.count || 0);
608
+ entry.count = count;
609
+ entry.notes = notes;
610
+ appData.total += diff;
611
+ } else {
612
+ // Create new entry
613
+ entry = { date: selectedDate, count: count, notes: notes };
614
+ appData.history.unshift(entry);
615
+ appData.total += count;
616
+ }
617
+
618
+ // If this is today's entry, update todayEntry reference
619
+ if (selectedDate === todayKey) {
620
+ todayEntry = entry;
621
+ }
622
+
623
+ saveData();
624
+ updateCounts();
625
+ renderHistory();
626
+ renderCharts();
627
+ closeModalHandler();
628
+ });
629
+
630
+ // Delete entry
631
+ deleteEntryBtn.addEventListener('click', function() {
632
+ const selectedDate = customDate.value;
633
+ const entryIndex = appData.history.findIndex(entry => entry.date === selectedDate);
634
+
635
+ if (entryIndex !== -1) {
636
+ const entry = appData.history[entryIndex];
637
+ appData.total -= entry.count;
638
+ appData.history.splice(entryIndex, 1);
639
+
640
+ saveData();
641
+ updateCounts();
642
+ renderHistory();
643
+ renderCharts();
644
+ closeModalHandler();
645
  }
646
  });
647
 
 
650
  todayCountEl.textContent = todayEntry.count;
651
  totalCountEl.textContent = appData.total;
652
 
653
+ // Update progress ring
654
+ updateProgressRing();
655
+
656
+ // Update total progress (simple visualization)
657
+ const maxTotal = 100; // Just for visualization purposes
658
+ const progressPercent = Math.min((appData.total / maxTotal) * 100, 100);
659
+ totalProgress.style.width = `${progressPercent}%`;
660
+
661
  // Add animation when count changes
662
  todayCountEl.classList.add('fade-in');
663
  totalCountEl.classList.add('fade-in');
 
677
  emptyState.style.display = 'none';
678
  historyList.innerHTML = '';
679
 
680
+ // Sort history by date (newest first)
681
+ const sortedHistory = [...appData.history].sort((a, b) => new Date(b.date) - new Date(a.date));
682
+
683
+ sortedHistory.forEach(entry => {
684
  if (entry.count === 0 && entry.date === todayKey) return;
685
 
686
  const entryDate = new Date(entry.date);
687
  const isToday = entry.date === todayKey;
688
 
689
+ let formattedEntryDate;
690
+ if (userSettings.timezone === 'auto') {
691
+ formattedEntryDate = moment(entry.date).format('ddd, MMM D, YYYY');
692
+ } else {
693
+ formattedEntryDate = moment.tz(entry.date, userSettings.timezone).format('ddd, MMM D, YYYY');
694
+ }
695
 
696
  const historyItem = document.createElement('div');
697
+ historyItem.className = 'flex justify-between items-center p-3 bg-gray-50 rounded-lg fade-in hover:bg-gray-100 cursor-pointer transition-colors';
698
  if (isToday) {
699
+ historyItem.classList.add('border-l-4', `border-${userSettings.theme}-500`);
700
  }
701
 
702
  historyItem.innerHTML = `
703
  <div class="flex items-center">
704
+ <div class="w-10 h-10 rounded-full bg-${userSettings.theme}-100 flex items-center justify-center mr-3">
705
+ <i class="fas fa-briefcase text-${userSettings.theme}-600"></i>
706
  </div>
707
  <div>
708
+ <p class="font-medium ${isToday ? `text-${userSettings.theme}-800` : 'text-gray-800'}">${formattedEntryDate}</p>
709
+ ${entry.notes ? `<p class="text-xs text-gray-500 truncate max-w-xs">${entry.notes}</p>` : ''}
710
  </div>
711
  </div>
712
+ <div class="flex items-center space-x-2">
713
+ <span class="text-lg font-bold ${isToday ? `text-${userSettings.theme}-800` : 'text-gray-700'}">${entry.count}</span>
714
+ </div>
715
  `;
716
 
717
+ // Add click handler to edit entry
718
+ historyItem.addEventListener('click', function() {
719
+ customDate.value = entry.date;
720
+ customCount.value = entry.count;
721
+ customNotes.value = entry.notes || '';
722
+ deleteEntryBtn.classList.remove('hidden');
723
+
724
+ // Change save button behavior to update existing entry
725
+ saveCustom.onclick = function() {
726
+ const newCount = parseInt(customCount.value);
727
+ const notes = customNotes.value.trim();
728
+
729
+ if (isNaN(newCount) || newCount < 0) {
730
+ alert('Please enter a valid number of applications');
731
+ return;
732
+ }
733
+
734
+ // Calculate the difference to update total correctly
735
+ const diff = newCount - entry.count;
736
+ entry.count = newCount;
737
+ entry.notes = notes;
738
+ appData.total += diff;
739
+
740
+ // If this is today's entry, update todayEntry reference
741
+ if (entry.date === todayKey) {
742
+ todayEntry = entry;
743
+ }
744
+
745
+ saveData();
746
+ updateCounts();
747
+ renderHistory();
748
+ renderCharts();
749
+ closeModalHandler();
750
+ };
751
+
752
+ openModal();
753
+ });
754
+
755
  historyList.appendChild(historyItem);
756
  });
757
  }
758
 
759
+ // Render charts
760
+ function renderCharts() {
761
+ // Weekly chart
762
+ const weeklyChart = document.querySelector('.flex.justify-between.items-end');
763
+ weeklyChart.innerHTML = '';
764
+
765
+ // Get last 7 days
766
+ const days = [];
767
+ for (let i = 6; i >= 0; i--) {
768
+ const date = new Date();
769
+ date.setDate(date.getDate() - i);
770
+ const dateKey = moment(date).format('YYYY-MM-DD');
771
+ days.push(dateKey);
772
+ }
773
+
774
+ // Find max count for scaling
775
+ let maxCount = 1;
776
+ days.forEach(day => {
777
+ const entry = appData.history.find(e => e.date === day);
778
+ if (entry && entry.count > maxCount) {
779
+ maxCount = entry.count;
780
+ }
781
+ });
782
+
783
+ // Create bars for each day
784
+ days.forEach(day => {
785
+ const entry = appData.history.find(e => e.date === day) || { count: 0 };
786
+ const heightPercent = (entry.count / maxCount) * 100;
787
+ const isToday = day === todayKey;
788
+
789
+ const dayName = moment(day).format('ddd');
790
+
791
+ const barContainer = document.createElement('div');
792
+ barContainer.className = 'flex flex-col items-center';
793
+
794
+ const bar = document.createElement('div');
795
+ bar.className = `chart-bar w-8 rounded-t-md bg-${userSettings.theme}-${isToday ? '600' : '400'} mb-1`;
796
+ bar.style.height = `${heightPercent}%`;
797
+ bar.style.minHeight = '4px';
798
+
799
+ const dayLabel = document.createElement('span');
800
+ dayLabel.className = 'text-xs text-gray-500';
801
+ dayLabel.textContent = dayName;
802
+
803
+ const countLabel = document.createElement('span');
804
+ countLabel.className = `text-xs font-medium text-${userSettings.theme}-800`;
805
+ countLabel.textContent = entry.count;
806
+
807
+ barContainer.appendChild(countLabel);
808
+ barContainer.appendChild(bar);
809
+ barContainer.appendChild(dayLabel);
810
+ weeklyChart.appendChild(barContainer);
811
+ });
812
+
813
+ // Monthly chart (simplified)
814
+ const monthlyChart = document.getElementById('monthly-chart');
815
+ monthlyChart.innerHTML = '';
816
+
817
+ // Create a simple bar for monthly progress
818
+ const thisMonth = moment().format('YYYY-MM');
819
+ const monthEntries = appData.history.filter(entry => entry.date.startsWith(thisMonth));
820
+ const monthTotal = monthEntries.reduce((sum, entry) => sum + entry.count, 0);
821
+
822
+ const monthContainer = document.createElement('div');
823
+ monthContainer.className = 'flex flex-col h-full justify-center';
824
+
825
+ const monthBar = document.createElement('div');
826
+ monthBar.className = `h-6 rounded-full bg-${userSettings.theme}-200 relative overflow-hidden`;
827
+
828
+ const monthProgress = document.createElement('div');
829
+ monthProgress.className = `absolute top-0 left-0 h-full bg-${userSettings.theme}-600 rounded-full`;
830
+ monthProgress.style.width = `${Math.min((monthTotal / 50) * 100, 100)}%`;
831
+
832
+ const monthText = document.createElement('div');
833
+ monthText.className = 'flex justify-between items-center mt-2';
834
+ monthText.innerHTML = `
835
+ <span class="text-sm text-gray-600">${moment().format('MMMM')}</span>
836
+ <span class="text-sm font-medium text-${userSettings.theme}-800">${monthTotal} apps</span>
837
+ `;
838
+
839
+ monthBar.appendChild(monthProgress);
840
+ monthContainer.appendChild(monthBar);
841
+ monthContainer.appendChild(monthText);
842
+ monthlyChart.appendChild(monthContainer);
843
+ }
844
+
845
  // Save data to localStorage
846
  function saveData() {
847
  localStorage.setItem('jobAppData', JSON.stringify(appData));
prompts.txt CHANGED
@@ -0,0 +1,2 @@
 
 
 
1
+ add a few functionalities for me to also decrease the number if I added by mistake. also let me choose another date if I want to add the number for previous days.
2
+ add option for decreasing as well. also you got the todays date wrong. add the option to add time zone or location so it can figure the todays day correct. also make the visualization better and delete the clear data option. add as many editing options as possible.