React hooks for saving, fetching, and deleting goal templates that can be reused to create new goals.
useTemplates
Fetch all goal templates for the current user.
const { data, isLoading, error } = useTemplates()
Returns
Array of goal templates, ordered by creation date (newest first)
Loading state of the query
Error object if the query failed
Example
import { useTemplates } from '@features/goals/api/use-templates'
function TemplatesList() {
const { data: templates, isLoading } = useTemplates()
if (isLoading) return <div>Loading templates...</div>
return (
<ul>
{templates?.map((template) => (
<li key={template.id}>
{template.name}
</li>
))}
</ul>
)
}
useSaveTemplate
Save a goal as a reusable template.
const { mutate, mutateAsync, isPending } = useSaveTemplate()
Returns
mutate
(params: SaveTemplateParams) => void
Function to save a template
mutateAsync
(params: SaveTemplateParams) => Promise<GoalTemplate>
Async function to save a template and await the result
Loading state of the mutation
Parameters
The goal structure to save as a template. Typically includes fields like title, description, end_date, and any sub-goals.
Example
import { useSaveTemplate } from '@features/goals/api/use-templates'
import { useGoal } from '@features/goals/api/use-goals'
function SaveAsTemplateButton({ goalId }: { goalId: string }) {
const { data: goal } = useGoal(goalId)
const { mutate: saveTemplate, isPending } = useSaveTemplate()
const handleSave = () => {
const name = prompt('Enter template name:')
if (!name || !goal) return
saveTemplate({
name,
goal: {
title: goal.title,
description: goal.description,
end_date: goal.end_date,
// Include any other fields you want in the template
},
})
}
return (
<button onClick={handleSave} disabled={isPending}>
Save as Template
</button>
)
}
useDeleteTemplate
Delete a goal template.
const { mutate, mutateAsync, isPending } = useDeleteTemplate()
Returns
mutate
(templateId: string) => void
Function to delete a template
mutateAsync
(templateId: string) => Promise<void>
Async function to delete a template and await completion
Loading state of the mutation
Parameters
The ID of the template to delete
Example
import { useDeleteTemplate } from '@features/goals/api/use-templates'
function DeleteTemplateButton({ templateId }: { templateId: string }) {
const { mutate: deleteTemplate, isPending } = useDeleteTemplate()
const handleDelete = () => {
if (confirm('Delete this template?')) {
deleteTemplate(templateId)
}
}
return (
<button onClick={handleDelete} disabled={isPending}>
Delete Template
</button>
)
}
Using templates to create goals
Templates can be used to quickly create new goals with predefined structures:
import { useTemplates } from '@features/goals/api/use-templates'
import { useCreateGoal } from '@features/goals/api/use-goals'
function CreateFromTemplate() {
const { data: templates } = useTemplates()
const { mutate: createGoal } = useCreateGoal()
const handleUseTemplate = (template: GoalTemplate) => {
createGoal(template.structure)
}
return (
<div>
<h2>Create from template</h2>
{templates?.map((template) => (
<button
key={template.id}
onClick={() => handleUseTemplate(template)}
>
{template.name}
</button>
))}
</div>
)
}