| 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 |
|
|