feat: public item detail view for shared and public setups
Items in shared/public setups are now viewable without auth. Clicking an item in a shared setup navigates to /items/:id?setup=:setupId&share=token which fetches the item via a public endpoint authorized by the setup's visibility or share token. Read-only mode hides all owner controls. - Added getSetupItemById service function - Added GET /api/shared/:token/items/:itemId endpoint - Added GET /api/setups/:setupId/items/:itemId/public endpoint - Added usePublicSetupItem and useSharedSetupItem hooks - Item detail page detects setup context and switches to public fetch - Back link returns to setup instead of collection in setup context Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -83,6 +83,51 @@ export function useSharedSetup(token: string | null) {
|
||||
});
|
||||
}
|
||||
|
||||
interface SetupItem {
|
||||
id: number;
|
||||
name: string;
|
||||
brand?: string | null;
|
||||
weightGrams: number | null;
|
||||
priceCents: number | null;
|
||||
quantity: number;
|
||||
categoryId: number;
|
||||
notes: string | null;
|
||||
productUrl: string | null;
|
||||
imageFilename: string | null;
|
||||
imageUrl?: string | null;
|
||||
globalItemId: number | null;
|
||||
createdAt: string;
|
||||
categoryName: string;
|
||||
categoryIcon: string;
|
||||
classification: string;
|
||||
}
|
||||
|
||||
export function usePublicSetupItem(
|
||||
setupId: number | null,
|
||||
itemId: number | null,
|
||||
) {
|
||||
return useQuery({
|
||||
queryKey: ["setups", setupId, "items", itemId, "public"],
|
||||
queryFn: () =>
|
||||
apiGet<SetupItem>(`/api/setups/${setupId}/items/${itemId}/public`),
|
||||
enabled: setupId != null && itemId != null,
|
||||
retry: (count, error) =>
|
||||
error instanceof ApiError && error.status === 404 ? false : count < 3,
|
||||
});
|
||||
}
|
||||
|
||||
export function useSharedSetupItem(
|
||||
token: string | null,
|
||||
itemId: number | null,
|
||||
) {
|
||||
return useQuery({
|
||||
queryKey: ["shared-setup", token, "items", itemId],
|
||||
queryFn: () => apiGet<SetupItem>(`/api/shared/${token}/items/${itemId}`),
|
||||
enabled: !!token && itemId != null,
|
||||
retry: false,
|
||||
});
|
||||
}
|
||||
|
||||
export function useCreateSetup() {
|
||||
const queryClient = useQueryClient();
|
||||
return useMutation({
|
||||
|
||||
Reference in New Issue
Block a user