2025-03-08 15:48:07 -05:00
|
|
|
// lib/hooks/useTemplates.ts
|
2025-03-17 23:37:08 -04:00
|
|
|
import { useState, useCallback, useEffect, useRef } from 'react';
|
2025-03-08 15:48:07 -05:00
|
|
|
import { WorkoutTemplate } from '@/types/templates';
|
|
|
|
import { useTemplateService } from '@/components/DatabaseProvider';
|
2025-03-17 23:37:08 -04:00
|
|
|
import { useTemplateRefresh } from '@/lib/stores/libraryStore';
|
2025-03-08 15:48:07 -05:00
|
|
|
|
|
|
|
export function useTemplates() {
|
|
|
|
const templateService = useTemplateService();
|
2025-03-17 23:37:08 -04:00
|
|
|
const { refreshCount, refreshTemplates, isLoading, setLoading } = useTemplateRefresh();
|
|
|
|
|
2025-03-08 15:48:07 -05:00
|
|
|
const [templates, setTemplates] = useState<WorkoutTemplate[]>([]);
|
|
|
|
const [error, setError] = useState<Error | null>(null);
|
2025-03-13 22:39:28 -04:00
|
|
|
const [archivedTemplates, setArchivedTemplates] = useState<WorkoutTemplate[]>([]);
|
2025-03-17 23:37:08 -04:00
|
|
|
|
|
|
|
// Add a loaded flag to track if we've successfully loaded templates at least once
|
|
|
|
const hasLoadedRef = useRef(false);
|
2025-03-08 15:48:07 -05:00
|
|
|
|
2025-03-17 23:37:08 -04:00
|
|
|
const loadTemplates = useCallback(async (limit: number = 50, offset: number = 0, showLoading: boolean = true) => {
|
2025-03-08 15:48:07 -05:00
|
|
|
try {
|
2025-03-17 23:37:08 -04:00
|
|
|
// Only show loading indicator if we haven't loaded before or if explicitly requested
|
|
|
|
if (showLoading && (!hasLoadedRef.current || templates.length === 0)) {
|
|
|
|
setLoading(true);
|
|
|
|
}
|
|
|
|
|
2025-03-08 15:48:07 -05:00
|
|
|
const data = await templateService.getAllTemplates(limit, offset);
|
|
|
|
setTemplates(data);
|
2025-03-17 23:37:08 -04:00
|
|
|
hasLoadedRef.current = true;
|
2025-03-08 15:48:07 -05:00
|
|
|
setError(null);
|
|
|
|
} catch (err) {
|
|
|
|
console.error('Error loading templates:', err);
|
|
|
|
setError(err instanceof Error ? err : new Error('Failed to load templates'));
|
|
|
|
// Use empty array if database isn't ready
|
|
|
|
setTemplates([]);
|
|
|
|
} finally {
|
|
|
|
setLoading(false);
|
|
|
|
}
|
2025-03-17 23:37:08 -04:00
|
|
|
}, [templateService, setLoading, templates.length]);
|
2025-03-08 15:48:07 -05:00
|
|
|
|
2025-03-17 23:37:08 -04:00
|
|
|
// Load templates when refreshCount changes
|
|
|
|
useEffect(() => {
|
|
|
|
loadTemplates();
|
|
|
|
}, [refreshCount, loadTemplates]);
|
|
|
|
|
|
|
|
// The rest of your methods remain the same
|
2025-03-08 15:48:07 -05:00
|
|
|
const getTemplate = useCallback(async (id: string) => {
|
|
|
|
try {
|
|
|
|
return await templateService.getTemplate(id);
|
|
|
|
} catch (err) {
|
|
|
|
console.error('Error getting template:', err);
|
|
|
|
throw err;
|
|
|
|
}
|
|
|
|
}, [templateService]);
|
|
|
|
|
|
|
|
const createTemplate = useCallback(async (template: Omit<WorkoutTemplate, 'id'>) => {
|
|
|
|
try {
|
2025-03-13 22:39:28 -04:00
|
|
|
// Add default values for new properties
|
|
|
|
const templateWithDefaults = {
|
|
|
|
...template,
|
|
|
|
isArchived: template.isArchived !== undefined ? template.isArchived : false,
|
|
|
|
};
|
|
|
|
|
|
|
|
const id = await templateService.createTemplate(templateWithDefaults);
|
2025-03-17 23:37:08 -04:00
|
|
|
refreshTemplates(); // Use the store's refresh function
|
2025-03-08 15:48:07 -05:00
|
|
|
return id;
|
|
|
|
} catch (err) {
|
|
|
|
console.error('Error creating template:', err);
|
|
|
|
throw err;
|
|
|
|
}
|
2025-03-17 23:37:08 -04:00
|
|
|
}, [templateService, refreshTemplates]);
|
2025-03-08 15:48:07 -05:00
|
|
|
|
|
|
|
const updateTemplate = useCallback(async (id: string, updates: Partial<WorkoutTemplate>) => {
|
|
|
|
try {
|
|
|
|
await templateService.updateTemplate(id, updates);
|
2025-03-17 23:37:08 -04:00
|
|
|
refreshTemplates(); // Use the store's refresh function
|
2025-03-08 15:48:07 -05:00
|
|
|
} catch (err) {
|
|
|
|
console.error('Error updating template:', err);
|
|
|
|
throw err;
|
|
|
|
}
|
2025-03-17 23:37:08 -04:00
|
|
|
}, [templateService, refreshTemplates]);
|
2025-03-08 15:48:07 -05:00
|
|
|
|
|
|
|
const deleteTemplate = useCallback(async (id: string) => {
|
|
|
|
try {
|
|
|
|
await templateService.deleteTemplate(id);
|
|
|
|
setTemplates(current => current.filter(t => t.id !== id));
|
2025-03-17 23:37:08 -04:00
|
|
|
refreshTemplates(); // Also trigger a refresh to ensure consistency
|
2025-03-08 15:48:07 -05:00
|
|
|
} catch (err) {
|
|
|
|
console.error('Error deleting template:', err);
|
|
|
|
throw err;
|
|
|
|
}
|
2025-03-17 23:37:08 -04:00
|
|
|
}, [templateService, refreshTemplates]);
|
2025-03-08 15:48:07 -05:00
|
|
|
|
2025-03-13 22:39:28 -04:00
|
|
|
const archiveTemplate = useCallback(async (id: string, archive: boolean = true) => {
|
|
|
|
try {
|
|
|
|
await templateService.archiveTemplate(id, archive);
|
2025-03-17 23:37:08 -04:00
|
|
|
refreshTemplates(); // Use the store's refresh function
|
2025-03-13 22:39:28 -04:00
|
|
|
} catch (err) {
|
|
|
|
console.error(`Error ${archive ? 'archiving' : 'unarchiving'} template:`, err);
|
|
|
|
throw err;
|
|
|
|
}
|
2025-03-17 23:37:08 -04:00
|
|
|
}, [templateService, refreshTemplates]);
|
2025-03-13 22:39:28 -04:00
|
|
|
|
|
|
|
const loadArchivedTemplates = useCallback(async (limit: number = 50, offset: number = 0) => {
|
|
|
|
try {
|
|
|
|
setLoading(true);
|
|
|
|
const data = await templateService.getArchivedTemplates(limit, offset);
|
|
|
|
setArchivedTemplates(data);
|
2025-03-17 23:37:08 -04:00
|
|
|
setError(null);
|
2025-03-13 22:39:28 -04:00
|
|
|
} catch (err) {
|
|
|
|
console.error('Error loading archived templates:', err);
|
|
|
|
setError(err instanceof Error ? err : new Error('Failed to load archived templates'));
|
2025-03-17 23:37:08 -04:00
|
|
|
setArchivedTemplates([]);
|
2025-03-13 22:39:28 -04:00
|
|
|
} finally {
|
|
|
|
setLoading(false);
|
|
|
|
}
|
2025-03-17 23:37:08 -04:00
|
|
|
}, [templateService, setLoading]);
|
2025-03-13 22:39:28 -04:00
|
|
|
|
2025-03-17 23:37:08 -04:00
|
|
|
// Add a silentRefresh method that doesn't show loading indicators
|
|
|
|
const silentRefresh = useCallback(() => {
|
|
|
|
loadTemplates(50, 0, false);
|
2025-03-08 15:48:07 -05:00
|
|
|
}, [loadTemplates]);
|
|
|
|
|
|
|
|
return {
|
|
|
|
templates,
|
2025-03-13 22:39:28 -04:00
|
|
|
archivedTemplates,
|
2025-03-17 23:37:08 -04:00
|
|
|
loading: isLoading,
|
2025-03-08 15:48:07 -05:00
|
|
|
error,
|
|
|
|
loadTemplates,
|
2025-03-17 23:37:08 -04:00
|
|
|
silentRefresh,
|
2025-03-13 22:39:28 -04:00
|
|
|
loadArchivedTemplates,
|
2025-03-08 15:48:07 -05:00
|
|
|
getTemplate,
|
|
|
|
createTemplate,
|
|
|
|
updateTemplate,
|
|
|
|
deleteTemplate,
|
2025-03-13 22:39:28 -04:00
|
|
|
archiveTemplate,
|
2025-03-17 23:37:08 -04:00
|
|
|
refreshTemplates
|
2025-03-08 15:48:07 -05:00
|
|
|
};
|
|
|
|
}
|