feat: implement real-time list synchronization
- Add useRealtimeSync hook for polling server updates every 3 seconds - Create API endpoint to check last updated timestamp for lists - Integrate real-time sync into ListDetailView component - Automatically refresh when other users make changes to shared lists - Poll on interval and when page becomes visible again
This commit is contained in:
82
app/api/lists/[id]/last-updated/route.ts
Normal file
82
app/api/lists/[id]/last-updated/route.ts
Normal file
@@ -0,0 +1,82 @@
|
||||
import { NextRequest, NextResponse } from 'next/server'
|
||||
import { prisma } from '@/lib/db'
|
||||
import { auth } from '@/auth'
|
||||
|
||||
export const dynamic = 'force-dynamic'
|
||||
export const revalidate = 0
|
||||
|
||||
export async function GET(
|
||||
request: NextRequest,
|
||||
{ params }: { params: { id: string } }
|
||||
) {
|
||||
try {
|
||||
const session = await auth()
|
||||
if (!session?.user?.id) {
|
||||
return NextResponse.json(
|
||||
{ error: 'Unauthorized' },
|
||||
{ status: 401 }
|
||||
)
|
||||
}
|
||||
|
||||
const userId = session.user.id
|
||||
const listId = params.id
|
||||
|
||||
// Check if user has access to this list
|
||||
const list = await prisma.list.findFirst({
|
||||
where: {
|
||||
id: listId,
|
||||
OR: [
|
||||
{ ownerId: userId },
|
||||
{
|
||||
collaborators: {
|
||||
some: {
|
||||
userId: userId,
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
select: {
|
||||
updatedAt: true,
|
||||
items: {
|
||||
select: {
|
||||
updatedAt: true,
|
||||
},
|
||||
orderBy: {
|
||||
updatedAt: 'desc',
|
||||
},
|
||||
take: 1,
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
if (!list) {
|
||||
return NextResponse.json(
|
||||
{ error: 'List not found or access denied' },
|
||||
{ status: 404 }
|
||||
)
|
||||
}
|
||||
|
||||
// Get the most recent update time (either list or its items)
|
||||
const listUpdated = list.updatedAt.getTime()
|
||||
const itemUpdated = list.items[0]?.updatedAt.getTime() || 0
|
||||
const lastUpdated = Math.max(listUpdated, itemUpdated)
|
||||
|
||||
return NextResponse.json(
|
||||
{ lastUpdated: new Date(lastUpdated).toISOString() },
|
||||
{
|
||||
headers: {
|
||||
'Cache-Control': 'no-store, no-cache, must-revalidate',
|
||||
'Pragma': 'no-cache',
|
||||
'Expires': '0',
|
||||
},
|
||||
}
|
||||
)
|
||||
} catch (error) {
|
||||
console.error('Error fetching last updated timestamp:', error)
|
||||
return NextResponse.json(
|
||||
{ error: 'Internal server error' },
|
||||
{ status: 500 }
|
||||
)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user