Skip to content

Commit 29ce5d5

Browse files
fix: Replace profile?.plan checks with isPaid state variable
- Removed undefined profile variable references - Fixed handleDisconnect to use setIsPaid instead of setProfile - Changed all isPaidPlan(profile?.plan) to isPaid - This was causing taskpane to fail loading and API key save to not work
1 parent f9977b3 commit 29ce5d5

2 files changed

Lines changed: 94 additions & 12 deletions

File tree

src/shared/api.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,12 @@ export async function fetchSeries(options: FetchOptions): Promise<FetchResult> {
164164
} else if (body.data) {
165165
// Data response - transform [{date, value}] to [[date, value]]
166166
const dataArray = body.data.map((obs: any) => [obs.date, obs.value]);
167-
transformedResponse = { data: dataArray, seriesId: body.seriesId };
167+
transformedResponse = {
168+
data: dataArray,
169+
seriesId: body.seriesId,
170+
status: body.status,
171+
message: body.message
172+
};
168173

169174
// Handle scalar modes (latest, value, yoy)
170175
if (mode === 'latest' && dataArray.length > 0) {

src/taskpane/App.tsx

Lines changed: 88 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ const App: React.FC = () => {
106106

107107
async function handleDisconnect() {
108108
await clearStoredApiKey();
109-
setProfile(null);
109+
setIsPaid(false);
110110
setView('disconnected');
111111
setMessage('Disconnected. Enter your API key to reconnect.');
112112
}
@@ -187,10 +187,17 @@ const App: React.FC = () => {
187187
fetchSeries({ seriesId, mode: 'meta', apiKey: key })
188188
]);
189189

190+
// Check if this is a metadata-only dataset
191+
const isMetadataOnly = latestRes.response?.status === 'metadata_only';
192+
const isPending = latestRes.response?.status === 'ingestion_pending';
193+
190194
setPreviewData({
191195
latest: latestRes.response?.scalar,
192196
meta: metaRes.response?.meta,
193-
error: latestRes.error || metaRes.error
197+
error: latestRes.error || metaRes.error,
198+
isMetadataOnly,
199+
isPending,
200+
statusMessage: latestRes.response?.message
194201
});
195202
setMessage('');
196203
} catch (err: any) {
@@ -199,6 +206,50 @@ const App: React.FC = () => {
199206
}
200207
}
201208

209+
async function requestFullIngestion(seriesId: string) {
210+
setMessage('Requesting full dataset ingestion...');
211+
const { key } = await getStoredApiKey();
212+
213+
try {
214+
const response = await fetch(`https://www.datasetiq.com/api/datasets/${seriesId}/fetch`, {
215+
method: 'POST',
216+
headers: {
217+
'Content-Type': 'application/json',
218+
...(key ? { 'Authorization': `Bearer ${key}` } : {})
219+
}
220+
});
221+
222+
const data = await response.json();
223+
224+
if (response.status === 401 || data.requiresAuth) {
225+
setMessage('⚠️ Authentication required. Visit datasetiq.com to sign up for full data access.');
226+
return;
227+
}
228+
229+
if (response.status === 429 || data.upgradeToPro) {
230+
setMessage(`⚠️ Monthly limit reached (${data.remaining || 0}/${data.limit || 100}). Upgrade to Pro for unlimited access.`);
231+
return;
232+
}
233+
234+
if (!response.ok) {
235+
setMessage(`⚠️ ${data.error || 'Failed to queue ingestion'}`);
236+
return;
237+
}
238+
239+
setMessage('✅ Dataset ingestion started! Data will be available in 1-2 minutes.');
240+
241+
// Update preview to show pending status
242+
setPreviewData(prev => ({
243+
...prev,
244+
isPending: true,
245+
statusMessage: 'Dataset ingestion queued. Full data will be available shortly.'
246+
}));
247+
248+
} catch (err: any) {
249+
setMessage(`⚠️ ${err.message || 'Failed to request ingestion'}`);
250+
}
251+
}
252+
202253
function checkPremiumAccess(feature: string): boolean {
203254
// Note: Premium plan detection not available from public API
204255
// All users have access to basic features only
@@ -482,16 +533,16 @@ const App: React.FC = () => {
482533
<button
483534
className={`tab premium-tab ${activeTab === 'builder' ? 'active' : ''}`}
484535
onClick={openBuilder}
485-
title={isPaidPlan(profile?.plan) ? 'Formula Builder' : 'Premium Feature'}
536+
title={isPaid ? 'Formula Builder' : 'Premium Feature'}
486537
>
487-
🔧 Builder {!isPaidPlan(profile?.plan) && '🔒'}
538+
🔧 Builder {!isPaid && '🔒'}
488539
</button>
489540
<button
490541
className={`tab premium-tab ${activeTab === 'templates' ? 'active' : ''}`}
491542
onClick={openTemplates}
492-
title={isPaidPlan(profile?.plan) ? 'Templates' : 'Premium Feature'}
543+
title={isPaid ? 'Templates' : 'Premium Feature'}
493544
>
494-
📁 Templates {!isPaidPlan(profile?.plan) && '🔒'}
545+
📁 Templates {!isPaid && '🔒'}
495546
</button>
496547
</div>
497548

@@ -512,7 +563,7 @@ const App: React.FC = () => {
512563
{results.length === 0 && <div className="muted">No results yet.</div>}
513564
{results.length > 0 && (
514565
<>
515-
{isPaidPlan(profile?.plan) && (
566+
{isPaid && (
516567
<div style={{marginBottom: '12px', padding: '8px', background: '#f0f9ff', borderRadius: '6px'}}>
517568
<label style={{display: 'flex', alignItems: 'center', gap: '6px', fontSize: '13px'}}>
518569
<input type="checkbox" onChange={(e) => {
@@ -534,7 +585,7 @@ const App: React.FC = () => {
534585
<ul>
535586
{results.map((r) => (
536587
<li key={r.id} className="result-item">
537-
{isPaidPlan(profile?.plan) && (
588+
{isPaid && (
538589
<input
539590
type="checkbox"
540591
checked={selectedForInsert.includes(r.id)}
@@ -882,12 +933,38 @@ const App: React.FC = () => {
882933
)}
883934
{previewData && !previewData.error && (
884935
<div className="preview-body">
936+
{/* Metadata-only notice */}
937+
{previewData.isMetadataOnly && (
938+
<div style={{marginBottom: '12px', padding: '10px', background: '#fef3c7', borderRadius: '6px', border: '1px solid #fbbf24'}}>
939+
<strong style={{color: '#92400e', display: 'block', marginBottom: '4px'}}>📊 Metadata Only</strong>
940+
<p style={{fontSize: '12px', color: '#78350f', margin: 0}}>
941+
This dataset hasn't been fully ingested yet. Click below to fetch the complete time-series data.
942+
</p>
943+
<button
944+
onClick={() => requestFullIngestion(previewSeries!)}
945+
style={{marginTop: '8px', width: '100%', padding: '8px', background: '#f59e0b', color: '#fff', border: 'none', borderRadius: '6px', fontWeight: '600', cursor: 'pointer'}}
946+
>
947+
🚀 Fetch Full Dataset
948+
</button>
949+
</div>
950+
)}
951+
952+
{/* Ingestion pending notice */}
953+
{previewData.isPending && (
954+
<div style={{marginBottom: '12px', padding: '10px', background: '#dbeafe', borderRadius: '6px', border: '1px solid '#3b82f6'}}>
955+
<strong style={{color: '#1e3a8a', display: 'block', marginBottom: '4px'}}>⏳ Ingestion In Progress</strong>
956+
<p style={{fontSize: '12px', color: '#1e40af', margin: 0}}>
957+
{previewData.statusMessage || 'Full dataset is being fetched. This usually takes 1-2 minutes. Please check back shortly.'}
958+
</p>
959+
</div>
960+
)}
961+
885962
<div className="preview-item">
886963
<strong>Latest Value:</strong> {previewData.latest ?? 'N/A'}
887-
<button className="copy-btn" onClick={() => navigator.clipboard.writeText(String(previewData.latest))} title="Copy">📋</button>
964+
{previewData.latest && <button className="copy-btn" onClick={() => navigator.clipboard.writeText(String(previewData.latest))} title="Copy">📋</button>}
888965
</div>
889966

890-
{isPaidPlan(profile?.plan) && previewData.meta && (
967+
{isPaid && previewData.meta && (
891968
<>
892969
<div className="premium-badge" style={{marginTop: '12px', marginBottom: '8px'}}>✨ Full Metadata (Premium)</div>
893970
{Object.entries(previewData.meta).map(([key, value]) => (
@@ -899,7 +976,7 @@ const App: React.FC = () => {
899976
</>
900977
)}
901978

902-
{!isPaidPlan(profile?.plan) && previewData.meta && (
979+
{!isPaid && previewData.meta && (
903980
<>
904981
{previewData.meta?.title && (
905982
<div className="preview-item">

0 commit comments

Comments
 (0)