Fix proxy endpoints and demo data mapping for live cross-service data
- rVote proxy: use space-scoped /api/s/{slug}/api/proposals instead of top-level
- rNotes proxy: fetch all notebooks and filter by slug server-side
- rCart demo: map carts array directly (each cart = one gear item)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
0d3d636751
commit
e5f4c7040e
|
|
@ -12,27 +12,34 @@ export async function GET(req: NextRequest) {
|
||||||
return NextResponse.json({ error: 'Missing endpoint param' }, { status: 400 });
|
return NextResponse.json({ error: 'Missing endpoint param' }, { status: 400 });
|
||||||
}
|
}
|
||||||
|
|
||||||
let targetUrl: string;
|
|
||||||
|
|
||||||
if (endpoint === 'notebook' && slug) {
|
|
||||||
// Get notebook by slug — use search with slug filter
|
|
||||||
targetUrl = `${RNOTES_BASE}/api/notebooks?slug=${encodeURIComponent(slug)}`;
|
|
||||||
} else if (endpoint === 'notes' && notebookId) {
|
|
||||||
targetUrl = `${RNOTES_BASE}/api/notebooks/${encodeURIComponent(notebookId)}/notes`;
|
|
||||||
} else {
|
|
||||||
return NextResponse.json({ error: 'Invalid endpoint or missing params' }, { status: 400 });
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const res = await fetch(targetUrl, { next: { revalidate: 30 } });
|
if (endpoint === 'notebook' && slug) {
|
||||||
if (!res.ok) {
|
// Fetch all notebooks and filter by slug (rNotes API doesn't support slug filter)
|
||||||
return NextResponse.json(
|
const res = await fetch(`${RNOTES_BASE}/api/notebooks`, { next: { revalidate: 30 } });
|
||||||
{ error: `Upstream error: ${res.status}` },
|
if (!res.ok) {
|
||||||
{ status: res.status }
|
return NextResponse.json({ error: `Upstream error: ${res.status}` }, { status: res.status });
|
||||||
|
}
|
||||||
|
const notebooks = await res.json();
|
||||||
|
const notebook = Array.isArray(notebooks)
|
||||||
|
? notebooks.find((nb: { slug: string }) => nb.slug === slug)
|
||||||
|
: null;
|
||||||
|
if (!notebook) {
|
||||||
|
return NextResponse.json({ error: 'Notebook not found' }, { status: 404 });
|
||||||
|
}
|
||||||
|
return NextResponse.json(notebook);
|
||||||
|
} else if (endpoint === 'notes' && notebookId) {
|
||||||
|
const res = await fetch(
|
||||||
|
`${RNOTES_BASE}/api/notebooks/${encodeURIComponent(notebookId)}/notes`,
|
||||||
|
{ next: { revalidate: 30 } }
|
||||||
);
|
);
|
||||||
|
if (!res.ok) {
|
||||||
|
return NextResponse.json({ error: `Upstream error: ${res.status}` }, { status: res.status });
|
||||||
|
}
|
||||||
|
const data = await res.json();
|
||||||
|
return NextResponse.json(data);
|
||||||
|
} else {
|
||||||
|
return NextResponse.json({ error: 'Invalid endpoint or missing params' }, { status: 400 });
|
||||||
}
|
}
|
||||||
const data = await res.json();
|
|
||||||
return NextResponse.json(data);
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
return NextResponse.json(
|
return NextResponse.json(
|
||||||
{ error: e instanceof Error ? e.message : 'Fetch failed' },
|
{ error: e instanceof Error ? e.message : 'Fetch failed' },
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ export async function GET(req: NextRequest) {
|
||||||
targetUrl = `${RVOTE_BASE}/api/spaces/${encodeURIComponent(slug)}`;
|
targetUrl = `${RVOTE_BASE}/api/spaces/${encodeURIComponent(slug)}`;
|
||||||
} else if (endpoint === 'proposals') {
|
} else if (endpoint === 'proposals') {
|
||||||
const status = searchParams.get('status') || 'RANKING';
|
const status = searchParams.get('status') || 'RANKING';
|
||||||
targetUrl = `${RVOTE_BASE}/api/proposals?spaceSlug=${encodeURIComponent(slug)}&status=${status}&limit=10`;
|
targetUrl = `${RVOTE_BASE}/api/s/${encodeURIComponent(slug)}/api/proposals?status=${status}&limit=10`;
|
||||||
} else {
|
} else {
|
||||||
return NextResponse.json({ error: 'Invalid endpoint' }, { status: 400 });
|
return NextResponse.json({ error: 'Invalid endpoint' }, { status: 400 });
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -676,18 +676,19 @@ export default function DemoContent() {
|
||||||
})
|
})
|
||||||
.then((data) => {
|
.then((data) => {
|
||||||
if (Array.isArray(data) && data.length > 0) {
|
if (Array.isArray(data) && data.length > 0) {
|
||||||
const cart = data[0]
|
setCartData(
|
||||||
if (cart.items?.length > 0) {
|
data.map((cart: Record<string, unknown>) => {
|
||||||
setCartData(
|
const target = Number(cart.targetAmount) || 100
|
||||||
cart.items.map((item: Record<string, unknown>) => ({
|
const funded = Number(cart.fundedAmount) || 0
|
||||||
item: item.name as string,
|
return {
|
||||||
target: (item.targetAmount as number) || 100,
|
item: cart.name as string,
|
||||||
funded: (item.fundedAmount as number) || 0,
|
target,
|
||||||
status: ((item.fundedAmount as number) || 0) >= ((item.targetAmount as number) || 100) ? 'Purchased' : 'Funding',
|
funded,
|
||||||
}))
|
status: (funded >= target ? 'Purchased' : 'Funding') as 'Purchased' | 'Funding',
|
||||||
)
|
}
|
||||||
setLiveFlags((f) => ({ ...f, cart: true }))
|
})
|
||||||
}
|
)
|
||||||
|
setLiveFlags((f) => ({ ...f, cart: true }))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch(() => {
|
.catch(() => {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue