Spaces:
Sleeping
Sleeping
| import React, { useState, useEffect } from 'react' | |
| import { | |
| Text, | |
| Stack, | |
| Box, | |
| UnstyledButton, | |
| Loader, | |
| Group, | |
| } from '@mantine/core' | |
| import { IconDatabase, IconFlask } from '@tabler/icons-react' | |
| import { useXRD } from '../context/XRDContext' | |
| const ExampleDataPanel = ({ onSelect }) => { | |
| const { loadExampleFile } = useXRD() | |
| const [examples, setExamples] = useState([]) | |
| const [loading, setLoading] = useState(true) | |
| const [loadingFile, setLoadingFile] = useState(null) | |
| useEffect(() => { | |
| const fetchExamples = async () => { | |
| try { | |
| const response = await fetch('/api/examples') | |
| if (response.ok) { | |
| const data = await response.json() | |
| setExamples(data) | |
| } | |
| } catch (err) { | |
| console.error('Failed to fetch examples:', err) | |
| } finally { | |
| setLoading(false) | |
| } | |
| } | |
| fetchExamples() | |
| }, []) | |
| const handleSelect = async (filename) => { | |
| setLoadingFile(filename) | |
| const success = await loadExampleFile(filename) | |
| setLoadingFile(null) | |
| if (success && onSelect) onSelect() | |
| } | |
| if (loading) { | |
| return ( | |
| <Box p="md" style={{ textAlign: 'center' }}> | |
| <Loader size="sm" /> | |
| </Box> | |
| ) | |
| } | |
| if (examples.length === 0) return null | |
| return ( | |
| <Box> | |
| <Group gap="xs" mb="xs"> | |
| <IconDatabase size={16} color="#868e96" /> | |
| <Text size="sm" fw={600} c="dimmed"> | |
| Example Data | |
| </Text> | |
| </Group> | |
| <Stack gap={8}> | |
| {examples.map((ex) => ( | |
| <UnstyledButton | |
| key={ex.filename} | |
| onClick={() => handleSelect(ex.filename)} | |
| disabled={loadingFile !== null} | |
| style={{ | |
| padding: '10px 12px', | |
| borderRadius: '8px', | |
| border: '1px solid #dee2e6', | |
| backgroundColor: loadingFile === ex.filename ? '#f1f3f5' : '#fff', | |
| cursor: loadingFile !== null ? 'wait' : 'pointer', | |
| transition: 'background-color 150ms ease', | |
| }} | |
| onMouseEnter={(e) => { | |
| if (!loadingFile) e.currentTarget.style.backgroundColor = '#f8f9fa' | |
| }} | |
| onMouseLeave={(e) => { | |
| if (loadingFile !== ex.filename) e.currentTarget.style.backgroundColor = '#fff' | |
| }} | |
| > | |
| <Group justify="space-between" align="center" wrap="nowrap"> | |
| <Group gap={6}> | |
| <IconFlask size={14} color="#7950f2" /> | |
| <Text size="sm" fw={500} truncate> | |
| {ex.material_id || ex.filename} | |
| </Text> | |
| </Group> | |
| {loadingFile === ex.filename && <Loader size={16} />} | |
| </Group> | |
| </UnstyledButton> | |
| ))} | |
| </Stack> | |
| </Box> | |
| ) | |
| } | |
| export default ExampleDataPanel | |