File size: 4,839 Bytes
255cbd1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
// API configuration for unified single-container deployment
const isServer = typeof window === 'undefined';
const API_BASE_URL = isServer ? 'http://localhost:8000/api' : '/api';

// ─────────────────────────────────────────────────────
// Generic interfaces – the profile page renders ANY
// shape of data; no domain-specific fields are assumed.
// ─────────────────────────────────────────────────────

export interface BusinessProfile {
  profile_id: string;
  job_id: string;
  business_type: string;
  business_info: Record<string, any>;
  products?: Record<string, any>[];
  services?: Record<string, any>[];
  created_at: string;
  updated_at?: string;
  extraction_metadata?: Record<string, any>;
  validation?: {
    completeness_score: number;
    field_scores: Record<string, number>;
  };
  [key: string]: any;
}

/** A single inventory item (product or service). Fully dynamic. */
export type InventoryItem = Record<string, any>;

export interface JobStatus {
  job_id: string;
  status: 'processing' | 'completed' | 'failed';
  progress: number;
  current_phase: string;
  error?: string;
}

export interface ProfileSummary {
  job_id: string;
  name: string;
  created_at: string;
  service_count: number;
  business_type: string;
}

// ─────────────────────────────────────────────────────
// API functions
// ─────────────────────────────────────────────────────

export async function uploadZip(file: File): Promise<{ job_id: string }> {
  const formData = new FormData();
  formData.append('file', file);

  const response = await fetch(`${API_BASE_URL}/upload`, {
    method: 'POST',
    body: formData,
  });

  if (!response.ok) {
    const error = await response.json();
    throw new Error(error.detail || 'Upload failed');
  }

  return response.json();
}

export interface SampleZip {
  name: string;
  filename: string;
  size_mb: number;
}

export async function getSamples(): Promise<{ samples: SampleZip[] }> {
  const response = await fetch(`${API_BASE_URL}/samples`);
  if (!response.ok) throw new Error('Failed to get samples');
  return response.json();
}

export async function runSample(filename: string): Promise<{ job_id: string }> {
  const response = await fetch(`${API_BASE_URL}/samples/${encodeURIComponent(filename)}/run`, {
    method: 'POST',
  });
  if (!response.ok) {
    const error = await response.json();
    throw new Error(error.detail || 'Failed to run sample');
  }
  return response.json();
}

export async function getJobStatus(jobId: string): Promise<JobStatus> {
  const response = await fetch(`${API_BASE_URL}/status/${jobId}`);

  if (!response.ok) {
    throw new Error('Failed to get status');
  }

  return response.json();
}

export async function getProfiles(): Promise<{ profiles: ProfileSummary[] }> {
  const response = await fetch(`${API_BASE_URL}/profiles`);

  if (!response.ok) {
    throw new Error('Failed to get profiles');
  }

  return response.json();
}

export async function getProfile(jobId: string): Promise<BusinessProfile> {
  const response = await fetch(`${API_BASE_URL}/profile/${jobId}`);

  if (!response.ok) {
    throw new Error('Profile not found');
  }

  return response.json();
}

export async function updateProfile(jobId: string, profile: BusinessProfile): Promise<{ success: boolean }> {
  const response = await fetch(`${API_BASE_URL}/profile/${jobId}`, {
    method: 'PUT',
    headers: {
      'Content-Type': 'application/json',
    },
    body: JSON.stringify(profile),
  });

  if (!response.ok) {
    throw new Error('Failed to update profile');
  }

  return response.json();
}

export async function deleteProfile(jobId: string): Promise<{ success: boolean }> {
  const response = await fetch(`${API_BASE_URL}/profile/${jobId}`, {
    method: 'DELETE',
  });

  if (!response.ok) {
    throw new Error('Failed to delete profile');
  }

  return response.json();
}

export async function exportProfile(jobId: string): Promise<void> {
  const response = await fetch(`${API_BASE_URL}/profile/${jobId}/export`);

  if (!response.ok) {
    throw new Error('Failed to export profile');
  }

  // Trigger download
  const blob = await response.blob();
  const url = window.URL.createObjectURL(blob);
  const a = document.createElement('a');
  a.href = url;
  a.download = `profile_${jobId}.json`;
  document.body.appendChild(a);
  a.click();
  window.URL.revokeObjectURL(url);
  document.body.removeChild(a);
}