complete_heir_functions

This commit is contained in:
lusixing
2026-02-02 19:40:49 -08:00
parent 5c1172a912
commit 6822638d47
5 changed files with 373 additions and 9 deletions

View File

@@ -40,6 +40,8 @@ export interface UseVaultAssetsReturn {
createAsset: (params: { title: string; content: string }) => Promise<CreateAssetResult>;
/** Delete asset via POST /assets/delete; on success refreshes list */
deleteAsset: (assetId: number) => Promise<CreateAssetResult>;
/** Assign asset to heir via POST /assets/assign */
assignAsset: (assetId: number, heirEmail: string) => Promise<CreateAssetResult>;
/** True while create request is in flight */
isSealing: boolean;
/** Error message from last create failure (non-401) */
@@ -68,10 +70,14 @@ export function useVaultAssets(isUnlocked: boolean): UseVaultAssetsReturn {
if (Array.isArray(list)) {
setAssets(mapApiAssetsToVaultAssets(list as ApiAsset[]));
}
} catch {
} catch (err: unknown) {
const rawMessage = err instanceof Error ? err.message : String(err ?? '');
if (/Could not validate credentials/i.test(rawMessage)) {
signOut();
}
// Keep current assets (mock or previous fetch)
}
}, [token]);
}, [token, signOut]);
// Fetch list when unlocked and token exists
useEffect(() => {
@@ -84,7 +90,13 @@ export function useVaultAssets(isUnlocked: boolean): UseVaultAssetsReturn {
setAssets(mapApiAssetsToVaultAssets(list as ApiAsset[]));
}
})
.catch(() => {
.catch((err) => {
if (!cancelled) {
const rawMessage = err instanceof Error ? err.message : String(err ?? '');
if (/Could not validate credentials/i.test(rawMessage)) {
signOut();
}
}
// Keep initial (mock) assets
});
return () => {
@@ -212,6 +224,44 @@ export function useVaultAssets(isUnlocked: boolean): UseVaultAssetsReturn {
[token, refreshAssets, signOut]
);
const assignAsset = useCallback(
async (assetId: number, heirEmail: string): Promise<CreateAssetResult> => {
if (!token) {
return { success: false, error: 'Not logged in.' };
}
setIsSealing(true);
setCreateError(null);
try {
await assetsService.assignAsset({ asset_id: assetId, heir_email: heirEmail }, token);
await refreshAssets();
return { success: true };
} catch (err: unknown) {
const status =
err && typeof err === 'object' && 'status' in err
? (err as { status?: number }).status
: undefined;
const rawMessage =
err instanceof Error ? err.message : String(err ?? 'Failed to assign.');
const isUnauthorized =
status === 401 || /401|Unauthorized/i.test(rawMessage);
if (isUnauthorized) {
signOut();
return { success: false, isUnauthorized: true };
}
const friendlyMessage = /failed to fetch|network error/i.test(rawMessage)
? 'Network error. Please check that the backend is running and reachable.'
: rawMessage;
setCreateError(friendlyMessage);
return { success: false, error: friendlyMessage };
} finally {
setIsSealing(false);
}
},
[token, signOut]
);
const clearCreateError = useCallback(() => setCreateError(null), []);
return {
@@ -220,6 +270,7 @@ export function useVaultAssets(isUnlocked: boolean): UseVaultAssetsReturn {
refreshAssets,
createAsset,
deleteAsset,
assignAsset,
isSealing,
createError,
clearCreateError,