Complete TypeScript migration

- Convert all shared components to TypeScript (.jsx → .tsx)
  - Carousel, ChartCard, EmptyState, FilterControls, StatCard, ToggleSwitch
- Add proper TypeScript interfaces for all component props
- Delete unused dataService.legacy.ts (archived Google Sheets code)
- Build passes successfully
This commit is contained in:
fahed
2026-02-04 13:59:56 +03:00
parent 868f46fc6e
commit d1c500a677
7 changed files with 100 additions and 110 deletions
-81
View File
@@ -1,81 +0,0 @@
// ============================================
// ARCHIVED - Google Sheets Data Fetching
// ============================================
// Kept for reference only - NOT used in the app
// The app now uses NocoDB exclusively with offline caching
const SPREADSHEET_ID = process.env.REACT_APP_SHEETS_ID || '';
const SHEET_NAME = process.env.REACT_APP_SHEETS_NAME || 'Consolidated Data';
const SHEET_URL = SPREADSHEET_ID
? `https://docs.google.com/spreadsheets/d/${SPREADSHEET_ID}/gviz/tq?tqx=out:csv&sheet=${encodeURIComponent(SHEET_NAME)}`
: '';
// Convert Excel serial date to YYYY-MM-DD
function excelDateToYMD(serial) {
const num = parseInt(serial);
if (isNaN(num) || num < 1) return null;
const utcDays = Math.floor(num - 25569);
const date = new Date(utcDays * 86400 * 1000);
const y = date.getUTCFullYear();
const m = String(date.getUTCMonth() + 1).padStart(2, '0');
const d = String(date.getUTCDate()).padStart(2, '0');
return `${y}-${m}-${d}`;
}
function parseCSV(text) {
const normalizedText = text.replace(/\r\n/g, '\n').replace(/\r/g, '\n');
const lines = normalizedText.trim().split('\n');
const headers = lines[0].split(',').map(h => h.trim().replace(/^"|"$/g, ''));
return lines.slice(1).map(line => {
const values = [];
let current = '';
let inQuotes = false;
for (let char of line) {
if (char === '"') {
inQuotes = !inQuotes;
} else if (char === ',' && !inQuotes) {
values.push(current.trim().replace(/^"|"$/g, ''));
current = '';
} else {
current += char;
}
}
values.push(current.trim().replace(/^"|"$/g, ''));
const obj = {};
headers.forEach((header, i) => {
let val = values[i] || '';
if (header === 'date' && /^\d+$/.test(val)) {
val = excelDateToYMD(val);
}
obj[header] = val;
});
return obj;
}).filter(row => row.date);
}
export async function fetchSheetData() {
try {
console.log('Fetching from Google Sheets...');
const response = await fetch(SHEET_URL);
if (!response.ok) throw new Error(`HTTP ${response.status}`);
const text = await response.text();
if (text.includes('<!DOCTYPE') || text.includes('<html')) {
throw new Error('Sheet is not public');
}
const data = parseCSV(text);
console.log(`Loaded ${data.length} rows from Google Sheets`);
return data;
} catch (err) {
console.error('Fetch error:', err);
throw new Error(`Failed to load data: ${err.message}`);
}
}