fix(cannaiq): Fix TypeScript build errors in ApiClient and pages
- Add put() method to ApiClient class - Update get() method to accept optional params config - Fix formatDuration to accept undefined type in JobQueue - Fix DiscoveryLocations API parameter (state -> stateCode) - Fix stats display path in DiscoveryLocations 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -35,8 +35,21 @@ class ApiClient {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Generic HTTP methods (axios-style interface)
|
// Generic HTTP methods (axios-style interface)
|
||||||
async get<T = any>(endpoint: string): Promise<{ data: T }> {
|
async get<T = any>(endpoint: string, config?: { params?: Record<string, any> }): Promise<{ data: T }> {
|
||||||
const data = await this.request<T>(endpoint);
|
let url = endpoint;
|
||||||
|
if (config?.params) {
|
||||||
|
const searchParams = new URLSearchParams();
|
||||||
|
Object.entries(config.params).forEach(([key, value]) => {
|
||||||
|
if (value !== undefined && value !== null) {
|
||||||
|
searchParams.append(key, String(value));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
const queryString = searchParams.toString();
|
||||||
|
if (queryString) {
|
||||||
|
url += (url.includes('?') ? '&' : '?') + queryString;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const data = await this.request<T>(url);
|
||||||
return { data };
|
return { data };
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -48,6 +61,14 @@ class ApiClient {
|
|||||||
return { data };
|
return { data };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async put<T = any>(endpoint: string, body?: any): Promise<{ data: T }> {
|
||||||
|
const data = await this.request<T>(endpoint, {
|
||||||
|
method: 'PUT',
|
||||||
|
body: body ? JSON.stringify(body) : undefined,
|
||||||
|
});
|
||||||
|
return { data };
|
||||||
|
}
|
||||||
|
|
||||||
// Auth
|
// Auth
|
||||||
async login(email: string, password: string) {
|
async login(email: string, password: string) {
|
||||||
return this.request<{ token: string; user: any }>('/api/auth/login', {
|
return this.request<{ token: string; user: any }>('/api/auth/login', {
|
||||||
|
|||||||
@@ -69,10 +69,25 @@ export function DiscoveryLocations() {
|
|||||||
try {
|
try {
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
const [locsData, statsData] = await Promise.all([
|
const [locsData, statsData] = await Promise.all([
|
||||||
api.getDiscoveryLocations({ state: stateFilter, status: statusFilter, limit: 500 }),
|
api.getDiscoveryLocations({ stateCode: stateFilter || undefined, status: statusFilter || undefined, limit: 500 }),
|
||||||
api.getDiscoveryStats(),
|
api.getDiscoveryStats(),
|
||||||
]);
|
]);
|
||||||
setLocations(locsData.locations || []);
|
// Map the API response to match our interface
|
||||||
|
const mappedLocations = (locsData.locations || []).map((loc: any) => ({
|
||||||
|
id: loc.id,
|
||||||
|
platform: loc.platform,
|
||||||
|
platform_location_id: loc.platformLocationId || loc.platform_location_id,
|
||||||
|
name: loc.name,
|
||||||
|
city: loc.city,
|
||||||
|
state_code: loc.stateCode || loc.state_code,
|
||||||
|
status: loc.status,
|
||||||
|
platform_menu_url: loc.platformMenuUrl || loc.platform_menu_url,
|
||||||
|
dispensary_id: loc.dispensaryId ?? loc.dispensary_id ?? null,
|
||||||
|
first_seen_at: loc.firstSeenAt || loc.first_seen_at,
|
||||||
|
last_seen_at: loc.lastSeenAt || loc.last_seen_at,
|
||||||
|
verified_at: loc.verifiedAt || loc.verified_at,
|
||||||
|
}));
|
||||||
|
setLocations(mappedLocations);
|
||||||
setStats(statsData);
|
setStats(statsData);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Failed to load discovery data:', error);
|
console.error('Failed to load discovery data:', error);
|
||||||
@@ -114,7 +129,7 @@ export function DiscoveryLocations() {
|
|||||||
<div>
|
<div>
|
||||||
<h1 className="text-2xl font-bold text-gray-900">Discovery Locations</h1>
|
<h1 className="text-2xl font-bold text-gray-900">Discovery Locations</h1>
|
||||||
<p className="text-sm text-gray-600">
|
<p className="text-sm text-gray-600">
|
||||||
Dutchie stores discovered via API - {stats?.total || 0} total
|
Dutchie stores discovered via API - {stats?.locations?.total || 0} total
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<button
|
<button
|
||||||
|
|||||||
@@ -72,7 +72,7 @@ interface JobsByType {
|
|||||||
count: string;
|
count: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
function formatDuration(ms: number | null): string {
|
function formatDuration(ms: number | null | undefined): string {
|
||||||
if (!ms) return '-';
|
if (!ms) return '-';
|
||||||
if (ms < 1000) return `${ms}ms`;
|
if (ms < 1000) return `${ms}ms`;
|
||||||
if (ms < 60000) return `${(ms / 1000).toFixed(1)}s`;
|
if (ms < 60000) return `${(ms / 1000).toFixed(1)}s`;
|
||||||
|
|||||||
Reference in New Issue
Block a user