SkateSpots/src/hooks/useMarkListingSold.ts
SkateSpots d1f8870379 chore(lint): remove all explicit any + sweep dead imports
- Fix all 12 no-explicit-any (NPool, NostrEvent[], LabProfile, structural
  Cluster type, explicit SkateSpot cast) -> 0 remaining
- Remove unused imports/vars across 48 files (manual + a verified codemod for
  unused import specifiers only); tsc + tests + boot smoke all green
- Warning backlog: 182 -> 76 (remaining: ~55 no-unused-vars locals,
  14 react-hooks/exhaustive-deps, 7 react-refresh)
- AGENTS.md baseline updated
2026-09-26 21:40:42 +07:00

52 lines
2 KiB
TypeScript

import { useQueryClient } from '@tanstack/react-query';
import { useNostrPublish } from '@/hooks/useNostrPublish';
import { useCurrentUser } from '@/hooks/useCurrentUser';
import { MARKETPLACE_ITEM_KIND } from '@/lib/types';
import type { NostrEvent } from '@nostrify/nostrify';
/**
* Flip a NIP-99 gear listing's status (active ⇄ sold).
*
* A listing (kind 30402) is addressable, so re-publishing REPLACES the whole
* tag set. We therefore start from the original event's tags and change ONLY
* the `status` tag — every other tag (title, price, images, size, spot `a`
* ref, geohash, expiration, published_at, category `t` tags…) is carried
* through untouched. Rebuilding from scratch here would wipe the listing's
* photos and price, so we deliberately don't.
*/
export function useMarkListingSold() {
const { mutateAsync: createEvent, isPending } = useNostrPublish();
const { user } = useCurrentUser();
const queryClient = useQueryClient();
const mutate = async ({
event,
status,
}: {
/** The original listing event. */
event: NostrEvent;
/** New status — 'sold' to mark sold, 'active' to relist. */
status: 'sold' | 'active';
}) => {
if (!user) throw new Error('You must be logged in.');
if (user.pubkey !== event.pubkey) throw new Error('You can only update your own listing.');
if (event.kind !== MARKETPLACE_ITEM_KIND) throw new Error('Not a gear listing.');
// Preserve every tag except `status`, then set the new status.
const tags = event.tags.filter(([name]) => name !== 'status');
tags.push(['status', status]);
await createEvent({
kind: MARKETPLACE_ITEM_KIND,
content: event.content,
tags,
});
// Refresh marketplace + seller views so the badge updates immediately.
queryClient.invalidateQueries();
};
return { markSold: (event: NostrEvent) => mutate({ event, status: 'sold' }),
relist: (event: NostrEvent) => mutate({ event, status: 'active' }),
isPending };
}