focus_Guard_test / src /components /Customise.jsx
k22056537
feat: UI nav, onboarding, L2CS weights path + torch.load; trim dev files
37a8ba6
import React, { useRef } from 'react';
function Customise() {
// Reference to the hidden import input.
const fileInputRef = useRef(null);
// 3. Export data.
const handleExport = async () => {
try {
// Fetch the full session history.
const response = await fetch('/api/sessions?filter=all');
if (!response.ok) throw new Error("Failed to fetch data");
const data = await response.json();
// Build a JSON blob for download.
const jsonString = JSON.stringify(data, null, 2);
// Keep a copy in local storage for quick recovery.
localStorage.setItem('focus_magic_backup', jsonString);
const blob = new Blob([jsonString], { type: 'application/json' });
// Create a temporary download link.
const url = URL.createObjectURL(blob);
const link = document.createElement('a');
link.href = url;
// Include the current date in the export filename.
link.download = `focus-guard-backup-${new Date().toISOString().slice(0, 10)}.json`;
// Trigger the browser download.
document.body.appendChild(link);
link.click();
// Clean up temporary elements and URLs.
document.body.removeChild(link);
URL.revokeObjectURL(url);
} catch (error) {
console.error(error);
alert("Export failed: " + error.message);
}
};
// 4. Trigger the import file chooser.
const triggerImport = () => {
fileInputRef.current.click();
};
// 5. Handle file import.
const handleFileChange = async (event) => {
const file = event.target.files[0];
if (!file) return;
const reader = new FileReader();
reader.onload = async (e) => {
try {
const content = e.target.result;
const sessions = JSON.parse(content);
// Basic validation: imported content must be an array.
if (!Array.isArray(sessions)) {
throw new Error("Invalid file format: Expected a list of sessions.");
}
// Send the imported payload to the backend for storage.
const response = await fetch('/api/import', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(sessions)
});
if (response.ok) {
const result = await response.json();
alert(`Success! Imported ${result.count} sessions.`);
} else {
alert("Import failed on server side.");
}
} catch (err) {
alert("Error parsing file: " + err.message);
}
// Reset the input so the same file can be selected again.
event.target.value = '';
};
reader.readAsText(file);
};
// 6. Clear all history.
const handleClearHistory = async () => {
if (!window.confirm("Are you sure? This will delete ALL your session history permanently.")) {
return;
}
try {
const response = await fetch('/api/history', { method: 'DELETE' });
if (response.ok) {
alert("All history has been cleared.");
} else {
alert("Failed to clear history.");
}
} catch (err) {
alert("Error: " + err.message);
}
};
return (
<main id="page-e" className="page">
<h1 className="page-title">Customise</h1>
<div className="settings-container">
{/* Data Management */}
<div className="setting-group">
<h2>Data Management</h2>
{/* Hidden file input that only accepts JSON files. */}
<input
type="file"
ref={fileInputRef}
style={{ display: 'none' }}
accept=".json"
onChange={handleFileChange}
/>
<div style={{ display: 'flex', gap: '10px', justifyContent: 'center', flexWrap: 'wrap' }}>
{/* Export button */}
<button id="export-data" className="action-btn blue" onClick={handleExport} style={{ width: '30%', minWidth: '120px' }}>
Export Data
</button>
{/* Import button */}
<button id="import-data" className="action-btn yellow" onClick={triggerImport} style={{ width: '30%', minWidth: '120px' }}>
Import Data
</button>
{/* Clear button */}
<button id="clear-history" className="action-btn red" onClick={handleClearHistory} style={{ width: '30%', minWidth: '120px' }}>
Clear History
</button>
</div>
</div>
</div>
</main>
);
}
export default Customise;