Skip to content

Commit 08e3341

Browse files
authored
Update index.html
1 parent fb513fa commit 08e3341

1 file changed

Lines changed: 67 additions & 107 deletions

File tree

time/index.html

Lines changed: 67 additions & 107 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
body { font-family: 'Inter', sans-serif; background-color: var(--color-bg); color: var(--color-text); }
2121
.wrap { max-width: 1200px; margin: 0 auto; padding: 2rem; }
2222

23+
/* Timeline Row Styling */
2324
.timeline-row {
2425
background: var(--color-card);
2526
border: 1px solid var(--color-line);
@@ -29,55 +30,40 @@
2930
display: flex;
3031
align-items: center;
3132
gap: 20px;
32-
animation: slideIn 0.3s ease-out;
3333
}
3434

35-
@keyframes slideIn { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: translateY(0); } }
36-
37-
.tz-info { width: 240px; flex-shrink: 0; border-right: 1px solid var(--color-line); padding-right: 15px; }
35+
.tz-info { width: 240px; flex-shrink: 0; border-right: 1px solid var(--color-line); }
3836

3937
.grid-viewport { flex-grow: 1; overflow-x: auto; scrollbar-width: none; }
4038
.grid-viewport::-webkit-scrollbar { display: none; }
4139

4240
.hour-grid { display: grid; grid-template-columns: repeat(24, 42px); gap: 4px; }
4341

4442
.hour-cell {
45-
height: 48px;
46-
background: rgba(255, 255, 255, 0.03);
43+
height: 48px; background: rgba(255, 255, 255, 0.03);
4744
border: 1px solid rgba(255, 255, 255, 0.08);
48-
border-radius: 6px;
49-
display: flex;
50-
flex-direction: column;
51-
align-items: center;
52-
justify-content: center;
53-
font-size: 0.7rem;
54-
cursor: pointer;
55-
transition: all 0.2s;
45+
border-radius: 6px; display: flex; flex-direction: column;
46+
align-items: center; justify-content: center; font-size: 0.7rem;
47+
cursor: pointer; transition: all 0.2s;
5648
}
5749

58-
.hour-cell:hover { border-color: var(--color-accent); background: rgba(255, 195, 0, 0.1); }
59-
.hour-cell.active {
60-
background: var(--color-accent) !important;
61-
color: var(--color-bg) !important;
62-
font-weight: 800;
63-
transform: scale(1.05);
64-
z-index: 10;
65-
}
50+
.hour-cell.active { background: var(--color-accent) !important; color: var(--color-bg) !important; font-weight: 800; transform: scale(1.05); z-index: 10; }
6651
.hour-cell.work { border-bottom: 3px solid #4ade80; }
6752
.hour-cell.night { opacity: 0.4; background: rgba(0,0,0,0.2); }
6853

69-
input#tz-search {
54+
/* Custom Dropdown/Search */
55+
.search-container { position: relative; width: 350px; }
56+
#tz-input {
7057
background: #0C1524; color: white; border: 1px solid var(--color-line);
71-
padding: 12px 18px; border-radius: 10px; width: 350px; outline: none;
72-
box-shadow: 0 4px 15px rgba(0,0,0,0.2);
58+
padding: 12px 18px; border-radius: 10px; width: 100%; outline: none;
7359
}
74-
input#tz-search:focus { border-color: var(--color-accent); }
75-
76-
.btn-add {
77-
background: var(--color-accent); color: var(--color-bg);
78-
font-weight: 800; padding: 12px 24px; border-radius: 10px;
79-
text-transform: uppercase; font-size: 0.75rem; letter-spacing: 1px;
60+
#tz-list {
61+
position: absolute; top: 110%; left: 0; width: 100%; max-height: 300px;
62+
background: #1e293b; border: 1px solid var(--color-line); border-radius: 10px;
63+
overflow-y: auto; z-index: 100; display: none; box-shadow: 0 10px 25px rgba(0,0,0,0.5);
8064
}
65+
.tz-option { padding: 10px 15px; cursor: pointer; font-size: 0.85rem; border-bottom: 1px solid rgba(255,255,255,0.05); }
66+
.tz-option:hover { background: var(--color-accent); color: var(--color-bg); font-weight: bold; }
8167
</style>
8268
</head>
8369
<body>
@@ -88,92 +74,78 @@
8874
<h1 class="text-3xl font-black text-white italic">TIME<span class="text-[--color-accent] not-italic">SYNC</span></h1>
8975
<p class="text-[10px] text-[--color-muted] font-bold tracking-[0.2em] mt-1 uppercase">Principal Engineering Toolkit</p>
9076
</div>
91-
<div class="flex gap-4">
92-
<a href="../stats" class="text-[--color-muted] hover:text-[--color-accent] flex items-center gap-2 text-xs font-bold uppercase">
93-
<i class="fa-solid fa-chart-simple"></i> Stats
94-
</a>
95-
<a href="../" class="bg-[--color-card] w-10 h-10 flex items-center justify-center rounded-xl border border-[--color-line] hover:border-[--color-accent] transition">
96-
<i class="fa-solid fa-house-user"></i>
97-
</a>
98-
</div>
77+
<a href="../" class="bg-[--color-card] w-10 h-10 flex items-center justify-center rounded-xl border border-[--color-line] hover:border-[--color-accent] transition">
78+
<i class="fa-solid fa-house-user"></i>
79+
</a>
9980
</header>
10081

10182
<div class="bg-[--color-card] p-6 rounded-2xl mb-8 border border-[--color-line] flex flex-wrap gap-6 items-center">
102-
<div class="flex flex-col gap-2">
103-
<span class="text-[10px] font-black text-[--color-muted] uppercase tracking-widest ml-1">Global Database Search</span>
104-
<div class="flex gap-3">
105-
<input type="text" id="tz-search" list="all-timezones" placeholder="Type city or country (e.g. London, UTC, IST)...">
106-
<datalist id="all-timezones"></datalist>
107-
<button onclick="addZone()" class="btn-add hover:brightness-110 active:scale-95 transition">Add Zone</button>
108-
</div>
83+
<div class="search-container">
84+
<span class="text-[10px] font-black text-[--color-muted] uppercase tracking-widest ml-1 mb-2 block">Search City / Region</span>
85+
<input type="text" id="tz-input" placeholder="Start typing (e.g. New York, Tokyo...)" onfocus="showList()" oninput="filterList()">
86+
<div id="tz-list"></div>
10987
</div>
11088

11189
<div class="ml-auto flex items-center gap-8">
11290
<div class="text-right border-r border-[--color-line] pr-8">
11391
<p class="text-[10px] uppercase text-[--color-muted] font-bold mb-1">Internal Reference</p>
11492
<p id="utc-clock" class="font-mono text-xl text-white font-black">00:00 <span class="text-[--color-accent] text-xs">UTC</span></p>
11593
</div>
116-
<button onclick="resetToNow()" class="text-[10px] font-black text-[--color-accent] border-2 border-[--color-accent] px-4 py-2 rounded-lg hover:bg-[--color-accent] hover:text-[--color-bg] transition-all">
117-
SYNC TO NOW
118-
</button>
94+
<button onclick="resetToNow()" class="text-[10px] font-black text-[--color-accent] border-2 border-[--color-accent] px-4 py-2 rounded-lg hover:bg-[--color-accent] hover:text-[--color-bg] transition-all uppercase">Sync to Now</button>
11995
</div>
12096
</div>
12197

122-
<div id="timeline-container" class="space-y-3">
123-
</div>
124-
125-
<div class="mt-8 p-4 bg-blue-900/10 border border-blue-900/30 rounded-xl flex items-center gap-4">
126-
<i class="fa-solid fa-circle-info text-blue-400"></i>
127-
<p class="text-xs text-blue-200/70"><b>Pro-Tip:</b> Click any hour cell to align the timeline. Green underlines indicate 9 AM - 5 PM business hours for that specific region.</p>
128-
</div>
98+
<div id="timeline-container" class="space-y-3"></div>
12999
</div>
130100

131101
<script>
132-
// Initial state: Only show the user's current local timezone
133102
let activeUtcIndex = new Date().getUTCHours();
134103
const localTZ = Intl.DateTimeFormat().resolvedOptions().timeZone;
135104
let selectedZones = [localTZ];
136-
137-
// Populate searchable IANA database
138105
const allZones = Intl.supportedValuesOf('timeZone');
139-
const datalist = document.getElementById('all-timezones');
140-
allZones.forEach(zone => {
141-
let opt = document.createElement('option');
142-
opt.value = zone;
143-
datalist.appendChild(opt);
106+
107+
// Setup Custom Search List
108+
const input = document.getElementById('tz-input');
109+
const list = document.getElementById('tz-list');
110+
111+
function showList() { list.style.display = 'block'; filterList(); }
112+
113+
// Hide list when clicking outside
114+
document.addEventListener('click', (e) => {
115+
if (!e.target.closest('.search-container')) list.style.display = 'none';
144116
});
145117

146-
function updateUTC() {
147-
const now = new Date();
148-
document.getElementById('utc-clock').innerHTML =
149-
`${now.getUTCHours().toString().padStart(2,'0')}:${now.getUTCMinutes().toString().padStart(2,'0')} <span class="text-[--color-accent] text-xs">UTC</span>`;
118+
function filterList() {
119+
const filter = input.value.toLowerCase();
120+
list.innerHTML = '';
121+
const filtered = allZones.filter(z => z.toLowerCase().includes(filter));
122+
123+
filtered.forEach(zone => {
124+
const div = document.createElement('div');
125+
div.className = 'tz-option';
126+
div.innerText = zone.replace(/_/g, ' ');
127+
div.onclick = () => {
128+
if (!selectedZones.includes(zone)) {
129+
selectedZones.push(zone);
130+
render();
131+
}
132+
input.value = '';
133+
list.style.display = 'none';
134+
};
135+
list.appendChild(div);
136+
});
150137
}
151138

152-
function addZone() {
153-
const input = document.getElementById('tz-search');
154-
const val = input.value;
155-
if (allZones.includes(val) && !selectedZones.includes(val)) {
156-
selectedZones.push(val);
157-
render();
158-
input.value = "";
159-
} else if (val === "UTC" && !selectedZones.includes("UTC")) {
160-
selectedZones.push("UTC");
161-
render();
162-
input.value = "";
163-
}
139+
function updateUTC() {
140+
const now = new Date();
141+
document.getElementById('utc-clock').innerHTML = `${now.getUTCHours().toString().padStart(2,'0')}:${now.getUTCMinutes().toString().padStart(2,'0')} <span class="text-[--color-accent] text-xs">UTC</span>`;
164142
}
165143

166144
function removeZone(index) {
167-
if (selectedZones.length > 1) {
168-
selectedZones.splice(index, 1);
169-
render();
170-
}
145+
if (selectedZones.length > 1) { selectedZones.splice(index, 1); render(); }
171146
}
172147

173-
function resetToNow() {
174-
activeUtcIndex = new Date().getUTCHours();
175-
render();
176-
}
148+
function resetToNow() { activeUtcIndex = new Date().getUTCHours(); render(); }
177149

178150
function render() {
179151
const container = document.getElementById('timeline-container');
@@ -182,45 +154,34 @@ <h1 class="text-3xl font-black text-white italic">TIME<span class="text-[--color
182154
selectedZones.forEach((zone, idx) => {
183155
const row = document.createElement('div');
184156
row.className = 'timeline-row';
185-
186157
const now = new Date();
187158
const timeInZone = now.toLocaleTimeString('en-US', { timeZone: zone, hour: '2-digit', minute: '2-digit', hour12: true });
188159
const offsetName = new Intl.DateTimeFormat('en-US', {timeZone: zone, timeZoneName:'short'}).formatToParts(now).find(p => p.type === 'timeZoneName').value;
189160

190161
row.innerHTML = `
191162
<div class="tz-info">
192-
<div class="flex justify-between items-center mb-1">
193-
<span class="font-black text-white text-sm tracking-tight">${zone.split('/').pop().replace('_', ' ')}</span>
163+
<div class="flex justify-between items-center mb-1 pr-4">
164+
<span class="font-black text-white text-sm tracking-tight">${zone.split('/').pop().replace(/_/g, ' ')}</span>
194165
<span class="text-[11px] font-mono text-[--color-accent] font-bold">${timeInZone}</span>
195166
</div>
196-
<div class="flex justify-between items-center">
167+
<div class="flex justify-between items-center pr-4">
197168
<span class="text-[9px] text-[--color-muted] font-bold uppercase tracking-tighter">${offsetName}</span>
198-
${idx !== 0 ? `<button onclick="removeZone(${idx})" class="text-[9px] font-black text-red-400/50 hover:text-red-400 uppercase tracking-widest">Delete</button>` : `<span class="text-[9px] text-blue-400 font-black uppercase tracking-widest">Local</span>`}
169+
${idx !== 0 ? `<button onclick="removeZone(${idx})" class="text-[9px] font-black text-red-400/50 hover:text-red-400 uppercase">Delete</button>` : `<span class="text-[9px] text-blue-400 font-black uppercase">Local</span>`}
199170
</div>
200171
</div>
201-
<div class="grid-viewport">
202-
<div class="hour-grid"></div>
203-
</div>
172+
<div class="grid-viewport"><div class="hour-grid" id="grid-${idx}"></div></div>
204173
`;
205174

206175
const grid = row.querySelector('.hour-grid');
207-
208-
// Build 24-hour UTC-aligned spine
209176
for (let i = 0; i < 24; i++) {
210177
const cell = document.createElement('div');
211-
const d = new Date();
212-
d.setUTCHours(i, 0, 0, 0);
213-
178+
const d = new Date(); d.setUTCHours(i, 0, 0, 0);
214179
const localHour = parseInt(d.toLocaleTimeString('en-US', { timeZone: zone, hour12: false, hour: 'numeric' }));
215180
const ampm = d.toLocaleTimeString('en-US', { timeZone: zone, hour: 'numeric', hour12: true }).split(' ')[1];
216-
217-
const isWork = localHour >= 9 && localHour <= 17;
218-
const isNight = localHour >= 22 || localHour <= 6;
219181
const isActive = i === activeUtcIndex;
220182

221-
cell.className = `hour-cell ${isWork ? 'work' : ''} ${isNight ? 'night' : ''} ${isActive ? 'active' : ''}`;
183+
cell.className = `hour-cell ${localHour >= 9 && localHour <= 17 ? 'work' : ''} ${localHour >= 22 || localHour <= 6 ? 'night' : ''} ${isActive ? 'active' : ''}`;
222184
cell.innerHTML = `<span class="text-xs font-bold">${localHour % 12 || 12}</span><span class="text-[7px] font-black uppercase opacity-60">${ampm}</span>`;
223-
224185
cell.onclick = () => { activeUtcIndex = i; render(); };
225186
grid.appendChild(cell);
226187
}
@@ -232,6 +193,5 @@ <h1 class="text-3xl font-black text-white italic">TIME<span class="text-[--color
232193
render();
233194
updateUTC();
234195
</script>
235-
236196
</body>
237197
</html>

0 commit comments

Comments
 (0)