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)
|
||||
async get<T = any>(endpoint: string): Promise<{ data: T }> {
|
||||
const data = await this.request<T>(endpoint);
|
||||
async get<T = any>(endpoint: string, config?: { params?: Record<string, any> }): Promise<{ data: T }> {
|
||||
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 };
|
||||
}
|
||||
|
||||
@@ -48,6 +61,14 @@ class ApiClient {
|
||||
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
|
||||
async login(email: string, password: string) {
|
||||
return this.request<{ token: string; user: any }>('/api/auth/login', {
|
||||
|
||||
@@ -69,10 +69,25 @@ export function DiscoveryLocations() {
|
||||
try {
|
||||
setLoading(true);
|
||||
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(),
|
||||
]);
|
||||
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);
|
||||
} catch (error) {
|
||||
console.error('Failed to load discovery data:', error);
|
||||
@@ -114,7 +129,7 @@ export function DiscoveryLocations() {
|
||||
<div>
|
||||
<h1 className="text-2xl font-bold text-gray-900">Discovery Locations</h1>
|
||||
<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>
|
||||
</div>
|
||||
<button
|
||||
|
||||
@@ -72,7 +72,7 @@ interface JobsByType {
|
||||
count: string;
|
||||
}
|
||||
|
||||
function formatDuration(ms: number | null): string {
|
||||
function formatDuration(ms: number | null | undefined): string {
|
||||
if (!ms) return '-';
|
||||
if (ms < 1000) return `${ms}ms`;
|
||||
if (ms < 60000) return `${(ms / 1000).toFixed(1)}s`;
|
||||
|
||||
Reference in New Issue
Block a user