Files
Todo/lib/actions.ts

193 lines
3.9 KiB
TypeScript

'use server'
import { prisma } from './db'
import { revalidatePath } from 'next/cache'
export async function getLists() {
return await prisma.list.findMany({
include: {
items: true,
},
orderBy: {
updatedAt: 'desc',
},
})
}
export async function createList(title: string, color: string = '#3B82F6') {
const list = await prisma.list.create({
data: {
title,
color,
},
})
revalidatePath('/')
return list
}
export async function getListWithItems(listId: string) {
return await prisma.list.findUnique({
where: { id: listId },
include: {
items: {
orderBy: {
createdAt: 'desc',
},
},
},
})
}
export async function createItem(listId: string, title: string, description?: string) {
const item = await prisma.item.create({
data: {
title,
description,
listId,
},
})
revalidatePath(`/list/${listId}`)
return item
}
export async function toggleItem(itemId: string) {
const item = await prisma.item.findUnique({ where: { id: itemId } })
if (!item) return null
const updated = await prisma.item.update({
where: { id: itemId },
data: { completed: !item.completed },
})
revalidatePath(`/list/${item.listId}`)
return updated
}
export async function updateItem(
itemId: string,
data: {
title?: string
description?: string | null
completed?: boolean
priority?: 'low' | 'medium' | 'high'
dueDate?: Date | null
tags?: string[]
notes?: string | null
}
) {
const item = await prisma.item.findUnique({ where: { id: itemId } })
if (!item) return null
const updated = await prisma.item.update({
where: { id: itemId },
data,
})
revalidatePath(`/list/${item.listId}`)
return updated
}
export async function deleteItem(itemId: string) {
const item = await prisma.item.findUnique({ where: { id: itemId } })
if (!item) return null
await prisma.item.delete({
where: { id: itemId },
})
revalidatePath(`/list/${item.listId}`)
return { success: true }
}
export async function deleteList(listId: string) {
await prisma.list.delete({
where: { id: listId },
})
revalidatePath('/')
return { success: true }
}
export async function updateList(
listId: string,
data: {
title?: string
color?: string
}
) {
const updated = await prisma.list.update({
where: { id: listId },
data,
})
revalidatePath('/')
revalidatePath(`/list/${listId}`)
return updated
}
export async function searchItems(query: string, listId?: string) {
if (!query.trim()) {
return []
}
const searchTerm = query.toLowerCase()
// Build the where clause
const whereClause: any = {
OR: [
{
title: {
contains: query,
mode: 'insensitive' as const,
},
},
{
description: {
contains: query,
mode: 'insensitive' as const,
},
},
{
notes: {
contains: query,
mode: 'insensitive' as const,
},
},
],
}
// Add list scope if specified
if (listId) {
whereClause.listId = listId
}
const items = await prisma.item.findMany({
where: whereClause,
include: {
list: true,
},
orderBy: {
updatedAt: 'desc',
},
})
// Also search in tags (stored as JSON)
const allItems = listId
? await prisma.item.findMany({
where: { listId },
include: { list: true },
})
: await prisma.item.findMany({
include: { list: true },
})
const tagMatches = allItems.filter((item) => {
const tags = Array.isArray(item.tags) ? item.tags : []
return tags.some((tag: string) =>
tag.toLowerCase().includes(searchTerm)
)
})
// Combine results and remove duplicates
const combinedResults = [...items, ...tagMatches]
const uniqueResults = Array.from(
new Map(combinedResults.map((item) => [item.id, item])).values()
)
return uniqueResults
}