refactor(api): standardize venues endpoint
Some checks failed
Deploy Fediversion / deploy (push) Failing after 1s
Some checks failed
Deploy Fediversion / deploy (push) Failing after 1s
- Backend: /api/venues returns PaginatedResponse envelope - Frontend: Updated VenuesPage, AdminVenuesPage, VerticalVenuesPage to consume envelope
This commit is contained in:
parent
c0e3e2a7e2
commit
3aaf35d43b
4 changed files with 34 additions and 27 deletions
|
|
@ -1,9 +1,9 @@
|
|||
from typing import List
|
||||
from fastapi import APIRouter, Depends, HTTPException, Query
|
||||
from sqlmodel import Session, select
|
||||
from sqlmodel import Session, select, func
|
||||
from database import get_session
|
||||
from models import Venue
|
||||
from schemas import VenueCreate, VenueRead, VenueUpdate
|
||||
from schemas import VenueCreate, VenueRead, VenueUpdate, PaginatedResponse, PaginationMeta
|
||||
from auth import get_current_user
|
||||
|
||||
router = APIRouter(prefix="/venues", tags=["venues"])
|
||||
|
|
@ -16,10 +16,14 @@ def create_venue(venue: VenueCreate, session: Session = Depends(get_session), cu
|
|||
session.refresh(db_venue)
|
||||
return db_venue
|
||||
|
||||
@router.get("/", response_model=List[VenueRead])
|
||||
@router.get("/", response_model=PaginatedResponse[VenueRead])
|
||||
def read_venues(offset: int = 0, limit: int = Query(default=1000, le=1000), session: Session = Depends(get_session)):
|
||||
total = session.exec(select(func.count()).select_from(Venue)).one()
|
||||
venues = session.exec(select(Venue).offset(offset).limit(limit)).all()
|
||||
return venues
|
||||
return PaginatedResponse(
|
||||
data=venues,
|
||||
meta=PaginationMeta(total=total, limit=limit, offset=offset)
|
||||
)
|
||||
|
||||
@router.get("/{slug}", response_model=VenueRead)
|
||||
def read_venue(slug: str, session: Session = Depends(get_session)):
|
||||
|
|
|
|||
|
|
@ -18,7 +18,8 @@ async function getVenues(verticalSlug: string) {
|
|||
next: { revalidate: 60 }
|
||||
})
|
||||
if (!res.ok) return []
|
||||
return res.json()
|
||||
const data = await res.json()
|
||||
return data.data || []
|
||||
} catch {
|
||||
return []
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
"use client"
|
||||
|
||||
import { useEffect, useState } from "react"
|
||||
import { useEffect, useState, useCallback } from "react"
|
||||
import { useAuth } from "@/contexts/auth-context"
|
||||
import { useRouter } from "next/navigation"
|
||||
import { Card, CardContent } from "@/components/ui/card"
|
||||
|
|
@ -38,6 +38,24 @@ export default function AdminVenuesPage() {
|
|||
const [editingVenue, setEditingVenue] = useState<Venue | null>(null)
|
||||
const [saving, setSaving] = useState(false)
|
||||
|
||||
const fetchVenues = useCallback(async () => {
|
||||
if (!token) return
|
||||
|
||||
try {
|
||||
const res = await fetch(`${getApiUrl()}/venues?limit=200`, {
|
||||
headers: { Authorization: `Bearer ${token}` }
|
||||
})
|
||||
if (res.ok) {
|
||||
const data = await res.json()
|
||||
setVenues(data.data || [])
|
||||
}
|
||||
} catch (e) {
|
||||
console.error("Failed to fetch venues", e)
|
||||
} finally {
|
||||
setLoading(false)
|
||||
}
|
||||
}, [token])
|
||||
|
||||
useEffect(() => {
|
||||
if (authLoading) return
|
||||
if (!user) {
|
||||
|
|
@ -49,25 +67,7 @@ export default function AdminVenuesPage() {
|
|||
return
|
||||
}
|
||||
fetchVenues()
|
||||
}, [user, router, authLoading])
|
||||
|
||||
const fetchVenues = async () => {
|
||||
if (!token) return
|
||||
|
||||
try {
|
||||
const res = await fetch(`${getApiUrl()}/venues?limit=200`, {
|
||||
headers: { Authorization: `Bearer ${token}` }
|
||||
})
|
||||
if (res.ok) {
|
||||
const data = await res.json()
|
||||
setVenues(data.venues || data)
|
||||
}
|
||||
} catch (e) {
|
||||
console.error("Failed to fetch venues", e)
|
||||
} finally {
|
||||
setLoading(false)
|
||||
}
|
||||
}
|
||||
}, [user, router, authLoading, fetchVenues])
|
||||
|
||||
const updateVenue = async () => {
|
||||
if (!token || !editingVenue) return
|
||||
|
|
|
|||
|
|
@ -34,11 +34,13 @@ export default function VenuesPage() {
|
|||
setError(null)
|
||||
// Fetch venues
|
||||
const venuesRes = await fetch(`${getApiUrl()}/venues/`)
|
||||
const venuesData: Venue[] = await venuesRes.json()
|
||||
const venuesEnvelope = await venuesRes.json()
|
||||
const venuesData: Venue[] = venuesEnvelope.data || []
|
||||
|
||||
// Fetch show counts for each venue (batch approach)
|
||||
const showsRes = await fetch(`${getApiUrl()}/shows/?limit=1000`)
|
||||
const showsData = await showsRes.json()
|
||||
const showsEnvelope = await showsRes.json()
|
||||
const showsData = showsEnvelope.data || []
|
||||
|
||||
// Count shows per venue
|
||||
const showCounts: Record<number, number> = {}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue