You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
165 lines
4.7 KiB
165 lines
4.7 KiB
import React, { useState, useEffect } from 'react'; |
|
import { css } from '@emotion/css'; |
|
import { GrafanaTheme2 } from '@grafana/data'; |
|
import { LinkButton, useStyles2, Input, Button, Alert } from '@grafana/ui'; |
|
import { prefixRoute } from '../utils/utils.routing'; |
|
import { ROUTES } from '../constants'; |
|
import { testIds } from '../components/testIds'; |
|
import { PluginPage, getBackendSrv } from '@grafana/runtime'; |
|
|
|
function PageOne() { |
|
const s = useStyles2(getStyles); |
|
const [textValue, setTextValue] = useState(''); |
|
const [savedValue, setSavedValue] = useState(''); |
|
const [loading, setLoading] = useState(false); |
|
const [error, setError] = useState(''); |
|
const [success, setSuccess] = useState(''); |
|
|
|
// Load saved value when component mounts |
|
useEffect(() => { |
|
loadSavedValue(); |
|
}, []); |
|
|
|
const loadSavedValue = async () => { |
|
try { |
|
const response = await getBackendSrv().get('/api/plugins/enne2corp-fullstacktest-app/resources/get-text'); |
|
setSavedValue(response.message || ''); |
|
} catch (err) { |
|
console.log('No saved value found or error loading:', err); |
|
setSavedValue(''); |
|
} |
|
}; |
|
|
|
const handleSaveText = async () => { |
|
if (!textValue.trim()) { |
|
setError('Please enter some text'); |
|
return; |
|
} |
|
|
|
setLoading(true); |
|
setError(''); |
|
setSuccess(''); |
|
|
|
try { |
|
await getBackendSrv().post('/api/plugins/enne2corp-fullstacktest-app/resources/save-text', { |
|
message: textValue, |
|
}); |
|
|
|
setSuccess('Text saved successfully!'); |
|
setSavedValue(textValue); |
|
setTextValue(''); |
|
|
|
// Clear success message after 3 seconds |
|
setTimeout(() => setSuccess(''), 3000); |
|
} catch (err) { |
|
setError('Failed to save text. Please try again.'); |
|
console.error('Error saving text:', err); |
|
} finally { |
|
setLoading(false); |
|
} |
|
}; |
|
|
|
return ( |
|
<PluginPage> |
|
<div data-testid={testIds.pageOne.container}> |
|
<h2>Welcome Message App</h2> |
|
|
|
{savedValue && ( |
|
<div className={s.welcomeMessage}> |
|
<h3>Welcome! Your saved message is:</h3> |
|
<p className={s.savedText}>{savedValue}</p> |
|
</div> |
|
)} |
|
|
|
{!savedValue && ( |
|
<div className={s.noMessage}> |
|
<p>No message saved yet. Enter a message below to get started!</p> |
|
</div> |
|
)} |
|
|
|
<div className={s.form}> |
|
<h4>Save a new message:</h4> |
|
<Input |
|
placeholder="Enter your message here..." |
|
value={textValue} |
|
onChange={(e) => setTextValue(e.currentTarget.value)} |
|
disabled={loading} |
|
className={s.input} |
|
/> |
|
|
|
<Button |
|
onClick={handleSaveText} |
|
disabled={loading || !textValue.trim()} |
|
className={s.button} |
|
> |
|
{loading ? 'Saving...' : 'Save Message'} |
|
</Button> |
|
</div> |
|
|
|
{error && ( |
|
<Alert title="Error" severity="error" className={s.alert}> |
|
{error} |
|
</Alert> |
|
)} |
|
|
|
{success && ( |
|
<Alert title="Success" severity="success" className={s.alert}> |
|
{success} |
|
</Alert> |
|
)} |
|
|
|
<div className={s.marginTop}> |
|
<LinkButton data-testid={testIds.pageOne.navigateToFour} href={prefixRoute(ROUTES.Four)}> |
|
Full-width page example |
|
</LinkButton> |
|
</div> |
|
</div> |
|
</PluginPage> |
|
); |
|
} |
|
|
|
export default PageOne; |
|
|
|
const getStyles = (theme: GrafanaTheme2) => ({ |
|
marginTop: css` |
|
margin-top: ${theme.spacing(2)}; |
|
`, |
|
welcomeMessage: css` |
|
background: ${theme.colors.background.secondary}; |
|
padding: ${theme.spacing(2)}; |
|
border-radius: ${theme.shape.borderRadius()}; |
|
margin-bottom: ${theme.spacing(2)}; |
|
border-left: 4px solid ${theme.colors.primary.main}; |
|
`, |
|
savedText: css` |
|
font-size: ${theme.typography.h4.fontSize}; |
|
font-weight: ${theme.typography.fontWeightMedium}; |
|
color: ${theme.colors.primary.text}; |
|
margin: 0; |
|
`, |
|
noMessage: css` |
|
background: ${theme.colors.warning.transparent}; |
|
padding: ${theme.spacing(2)}; |
|
border-radius: ${theme.shape.borderRadius()}; |
|
margin-bottom: ${theme.spacing(2)}; |
|
border-left: 4px solid ${theme.colors.warning.main}; |
|
`, |
|
form: css` |
|
background: ${theme.colors.background.secondary}; |
|
padding: ${theme.spacing(2)}; |
|
border-radius: ${theme.shape.borderRadius()}; |
|
margin-bottom: ${theme.spacing(2)}; |
|
`, |
|
input: css` |
|
margin-bottom: ${theme.spacing(2)}; |
|
width: 100%; |
|
max-width: 400px; |
|
`, |
|
button: css` |
|
margin-top: ${theme.spacing(1)}; |
|
`, |
|
alert: css` |
|
margin-top: ${theme.spacing(2)}; |
|
margin-bottom: ${theme.spacing(2)}; |
|
`, |
|
});
|
|
|