Spaces:
Running
Running
| 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; | |