admin page
This commit is contained in:
@@ -6,6 +6,7 @@ import type {
|
||||
DocumentResponse,
|
||||
Organization,
|
||||
OrganizationListResponse,
|
||||
PurchaseRequestListResponse,
|
||||
UpdateOrganizationRequest,
|
||||
WalletResponse,
|
||||
} from '../model/types'
|
||||
@@ -120,18 +121,15 @@ export function createOrganizationWallets(id: string): Promise<WalletResponse[]>
|
||||
)
|
||||
}
|
||||
|
||||
export async function getDocuments(orgId: string): Promise<DocumentResponse[]> {
|
||||
const data = await doAdminRequest<DocumentResponse[]>(
|
||||
export function getDocuments(orgId: string): Promise<DocumentResponse[]> {
|
||||
return doAdminRequest<DocumentResponse[]>(
|
||||
`/v1/organizations/${orgId}/documents`,
|
||||
{},
|
||||
true,
|
||||
)
|
||||
// TEMP: inspect the real backend shape (download_url presence, fields).
|
||||
console.log('[documents] list response:', data)
|
||||
return data
|
||||
}
|
||||
|
||||
export async function uploadDocument(
|
||||
export function uploadDocument(
|
||||
orgId: string,
|
||||
documentType: string,
|
||||
file: File,
|
||||
@@ -140,27 +138,32 @@ export async function uploadDocument(
|
||||
body.append('document_type', documentType)
|
||||
body.append('file', file)
|
||||
|
||||
const data = await doAdminRequest<DocumentResponse>(
|
||||
return doAdminRequest<DocumentResponse>(
|
||||
`/v1/organizations/${orgId}/documents`,
|
||||
{ method: 'POST', body },
|
||||
true,
|
||||
)
|
||||
// TEMP: inspect the real backend shape after upload.
|
||||
console.log('[documents] upload response:', data)
|
||||
return data
|
||||
}
|
||||
|
||||
export async function getDocument(
|
||||
orgId: string,
|
||||
documentId: string,
|
||||
): Promise<DocumentResponse> {
|
||||
const data = await doAdminRequest<DocumentResponse>(
|
||||
`/v1/organizations/${orgId}/documents/${documentId}`,
|
||||
export async function getPurchaseRequests(params: {
|
||||
organizationId?: string
|
||||
status?: string
|
||||
limit?: number
|
||||
offset?: number
|
||||
}): Promise<PurchaseRequestListResponse> {
|
||||
const query = new URLSearchParams()
|
||||
if (params.organizationId) query.set('organization_id', params.organizationId)
|
||||
if (params.status) query.set('status', params.status)
|
||||
query.set('limit', String(params.limit ?? 50))
|
||||
query.set('offset', String(params.offset ?? 0))
|
||||
|
||||
const data = await doAdminRequest<PurchaseRequestListResponse>(
|
||||
`/v1/purchase-requests?${query.toString()}`,
|
||||
{},
|
||||
true,
|
||||
)
|
||||
// TEMP: inspect single-document shape (this is where download_url should appear).
|
||||
console.log('[documents] get-one response:', data)
|
||||
// TEMP: inspect real backend shape — especially which `status` values appear.
|
||||
console.log('[purchase-requests] list response:', data)
|
||||
return data
|
||||
}
|
||||
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
import { useState } from 'react'
|
||||
import { getDocument } from '../api/adminApi'
|
||||
import type { DocumentResponse } from '../model/types'
|
||||
|
||||
/**
|
||||
* Resolves a document's download URL and opens it. The list endpoint may not
|
||||
* include a fresh `download_url`, so we fall back to fetching the single
|
||||
* document (which is where the presigned URL is expected to appear).
|
||||
*/
|
||||
export function useDownloadDocument(orgId: string) {
|
||||
const [downloadingId, setDownloadingId] = useState<string | null>(null)
|
||||
|
||||
async function download(doc: DocumentResponse) {
|
||||
setDownloadingId(doc.id)
|
||||
try {
|
||||
let url = doc.download_url
|
||||
if (!url) {
|
||||
const fresh = await getDocument(orgId, doc.id)
|
||||
url = fresh.download_url
|
||||
}
|
||||
if (url) {
|
||||
window.open(url, '_blank', 'noopener,noreferrer')
|
||||
} else {
|
||||
throw new Error('Сервер не вернул ссылку для скачивания')
|
||||
}
|
||||
} finally {
|
||||
setDownloadingId(null)
|
||||
}
|
||||
}
|
||||
|
||||
return { download, downloadingId }
|
||||
}
|
||||
15
src/features/admin/hooks/usePurchaseRequests.ts
Normal file
15
src/features/admin/hooks/usePurchaseRequests.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
import { useQuery } from '@tanstack/react-query'
|
||||
import { getPurchaseRequests } from '../api/adminApi'
|
||||
|
||||
export const PURCHASE_REQUESTS_QUERY_KEY = (orgId: string) => [
|
||||
'admin-purchase-requests',
|
||||
orgId,
|
||||
]
|
||||
|
||||
export function usePurchaseRequests(orgId: string | undefined) {
|
||||
return useQuery({
|
||||
queryKey: PURCHASE_REQUESTS_QUERY_KEY(orgId ?? ''),
|
||||
queryFn: () => getPurchaseRequests({ organizationId: orgId }),
|
||||
enabled: !!orgId,
|
||||
})
|
||||
}
|
||||
@@ -9,7 +9,7 @@ export {
|
||||
updateOrganization,
|
||||
getDocuments,
|
||||
uploadDocument,
|
||||
getDocument,
|
||||
getPurchaseRequests,
|
||||
refreshAdminToken,
|
||||
adminTokenStore,
|
||||
} from './api/adminApi'
|
||||
@@ -23,6 +23,8 @@ export type {
|
||||
UpdateOrganizationRequest,
|
||||
WalletResponse,
|
||||
DocumentResponse,
|
||||
PurchaseRequestResponse,
|
||||
PurchaseRequestListResponse,
|
||||
BankDetails,
|
||||
} from './model/types'
|
||||
export { useAdminAuth, ADMIN_AUTH_QUERY_KEY } from './hooks/useAdminAuth'
|
||||
@@ -35,4 +37,4 @@ export { useCreateOrganizationWallets } from './hooks/useCreateOrganizationWalle
|
||||
export { useUpdateOrganization } from './hooks/useUpdateOrganization'
|
||||
export { useDocuments, DOCUMENTS_QUERY_KEY } from './hooks/useDocuments'
|
||||
export { useUploadDocument } from './hooks/useUploadDocument'
|
||||
export { useDownloadDocument } from './hooks/useDownloadDocument'
|
||||
export { usePurchaseRequests, PURCHASE_REQUESTS_QUERY_KEY } from './hooks/usePurchaseRequests'
|
||||
|
||||
@@ -70,6 +70,31 @@ export interface DocumentResponse {
|
||||
download_url: string | null
|
||||
}
|
||||
|
||||
// Monetary fields are strings to preserve decimal precision — do not coerce to number.
|
||||
export interface PurchaseRequestResponse {
|
||||
id: string
|
||||
organization_id: string
|
||||
status: string
|
||||
usdt_amount: string
|
||||
rub_amount: string | null
|
||||
exchange_rate: string | null
|
||||
service_fee_percent: string | null
|
||||
comment: string | null
|
||||
admin_comment: string | null
|
||||
target_wallet_chain: string | null
|
||||
target_wallet_address: string | null
|
||||
tx_hash: string | null
|
||||
assigned_to: string | null
|
||||
created_at: string | null
|
||||
updated_at: string | null
|
||||
completed_at: string | null
|
||||
}
|
||||
|
||||
export interface PurchaseRequestListResponse {
|
||||
items: PurchaseRequestResponse[]
|
||||
total: number
|
||||
}
|
||||
|
||||
export interface UpdateOrganizationRequest {
|
||||
name?: string | null
|
||||
short_name?: string | null
|
||||
|
||||
Reference in New Issue
Block a user