Skip to content

Commit c3b2aab

Browse files
committed
refactor(habits-widget): add tabs to switch between counters and history
- Replace static counters and history sections with tabbed interface - Add buttons to switch tabs and style active/inactive states - Create switchHabitsTab function to toggle tab visibility and update styles - Update DOM utils to support multiple class removals - Expose switchHabitsTab function on global window object for event handling
1 parent cd243e2 commit c3b2aab

File tree

3 files changed

+85
-9
lines changed

3 files changed

+85
-9
lines changed

web/src/server/utils/dom-utils.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -101,10 +101,10 @@ export function addClass(
101101
*/
102102
export function removeClass(
103103
element: HTMLElement | null,
104-
className: string
104+
...classNames: string[]
105105
): void {
106106
if (element && element.classList) {
107-
element.classList.remove(className);
107+
element.classList.remove(...classNames);
108108
}
109109
}
110110

web/src/server/widgets/habits-widget.ts

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -321,15 +321,32 @@ export class HabitsWidgetRender implements WidgetRender<HabitsWidgetType> {
321321
</button>
322322
</div>
323323
324-
<div class="grid grid-cols-2 sm:grid-cols-4 gap-4 mb-8" id="${modalId}-tracking-items-container">
325-
<!-- Dynamic items will be inserted here by JavaScript -->
324+
<!-- Tabs -->
325+
<div class="flex border-b border-gray-200 mb-6">
326+
<button class="tab-button py-2 px-4 font-medium text-gray-700 border-b-2 border-transparent hover:text-pastel-blue hover:border-pastel-blue focus:outline-none"
327+
onclick="switchHabitsTab('${modalId}', 'counters')">
328+
Counters
329+
</button>
330+
<button class="tab-button py-2 px-4 font-medium text-gray-700 border-b-2 border-transparent hover:text-pastel-blue hover:border-pastel-blue focus:outline-none"
331+
onclick="switchHabitsTab('${modalId}', 'history')">
332+
History
333+
</button>
334+
</div>
335+
336+
<!-- Tab Content -->
337+
<div id="${modalId}-counters-tab" class="tab-content">
338+
<div class="grid grid-cols-2 sm:grid-cols-4 gap-4 mb-8" id="${modalId}-tracking-items-container">
339+
<!-- Dynamic items will be inserted here by JavaScript -->
340+
</div>
326341
</div>
327342
328-
<div class="border-t border-gray-100 pt-4">
329-
<h3 class="text-lg font-bold text-gray-800 mb-3">History</h3>
330-
<div id="${modalId}-consumption-list" class="max-h-60 overflow-y-auto pr-2">
331-
<!-- Items will be added dynamically -->
332-
<p class="text-gray-500 text-center py-4" id="${modalId}-no-consumption-message">No records</p>
343+
<div id="${modalId}-history-tab" class="tab-content hidden">
344+
<div class="border-t border-gray-100 pt-4">
345+
<h3 class="text-lg font-bold text-gray-800 mb-3">History</h3>
346+
<div id="${modalId}-consumption-list" class="max-h-60 overflow-y-auto pr-2">
347+
<!-- Items will be added dynamically -->
348+
<p class="text-gray-500 text-center py-4" id="${modalId}-no-consumption-message">No records</p>
349+
</div>
333350
</div>
334351
</div>
335352
</div>

web/src/server/widgets/habits-widget.utils.ts

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -582,6 +582,64 @@ export function hideHabitsModal(
582582
}
583583
}
584584

585+
/**
586+
* Switches between tabs in the habits modal
587+
* @param modalId - ID of the modal element
588+
* @param tabName - Name of the tab to switch to ('counters' or 'history')
589+
* @param scope - Document or element scope for DOM operations
590+
*/
591+
function switchHabitsTab(
592+
modalId: string,
593+
tabName: 'counters' | 'history',
594+
scope: Document | HTMLElement = document
595+
): void {
596+
// Hide all tab contents
597+
const countersTab = getElementById(scope, `${modalId}-counters-tab`);
598+
const historyTab = getElementById(scope, `${modalId}-history-tab`);
599+
600+
if (countersTab) {
601+
if (tabName === 'counters') {
602+
removeClass(countersTab, 'hidden');
603+
} else {
604+
addClass(countersTab, 'hidden');
605+
}
606+
}
607+
608+
if (historyTab) {
609+
if (tabName === 'history') {
610+
removeClass(historyTab, 'hidden');
611+
} else {
612+
addClass(historyTab, 'hidden');
613+
}
614+
}
615+
616+
// Update tab button styles
617+
const tabButtons = scope.querySelectorAll('.tab-button');
618+
tabButtons.forEach(button => {
619+
removeClass(
620+
button as HTMLElement,
621+
'text-pastel-blue',
622+
'border-pastel-blue'
623+
);
624+
addClass(button as HTMLElement, 'text-gray-700', 'border-transparent');
625+
});
626+
627+
// Highlight active tab button
628+
const activeButton = scope.querySelector(`button[onclick*="'${tabName}'"]`);
629+
if (activeButton) {
630+
removeClass(
631+
activeButton as HTMLElement,
632+
'text-gray-700',
633+
'border-transparent'
634+
);
635+
addClass(
636+
activeButton as HTMLElement,
637+
'text-pastel-blue',
638+
'border-pastel-blue'
639+
);
640+
}
641+
}
642+
585643
export const linkFunctionsToWindow = (): void => {
586644
// Export all utility functions
587645
if (WINDOW) {
@@ -595,5 +653,6 @@ export const linkFunctionsToWindow = (): void => {
595653
WINDOW.initTrackingItems = initTrackingItems;
596654
WINDOW.showHabitsModal = showHabitsModal;
597655
WINDOW.hideHabitsModal = hideHabitsModal;
656+
WINDOW.switchHabitsTab = switchHabitsTab; // Add the new function
598657
}
599658
};

0 commit comments

Comments
 (0)