diff --git a/frontend/CommitHash.js b/frontend/CommitHash.js new file mode 100644 index 00000000..e69de29b diff --git a/frontend/components/Admin/Theme.js b/frontend/components/Admin/Theme.js index 3a65363a..2fbd36ed 100644 --- a/frontend/components/Admin/Theme.js +++ b/frontend/components/Admin/Theme.js @@ -5,16 +5,15 @@ import Loading from '../Reusable/Loading'; import { addError } from '../../redux/actions'; import { useDispatch, useSelector } from 'react-redux'; import { useState, useEffect } from 'react'; -import Loader from 'react-loader-spinner'; import { isValidURI } from '../Viewing/Shell'; const { publicRuntimeConfig } = getConfig(); export default function Theme() { const dispatch = useDispatch(); - const [loading, setLoading] = useState(true); // Initialize loading state to true + const [loading, setLoading] = useState(true); const [theme, setTheme] = useState({}); - const [instanceName, setInstanceName] = useState(''); // Default to empty - const [frontPageText, setFrontPageText] = useState(''); // Default to empty + const [instanceName, setInstanceName] = useState(''); + const [frontPageText, setFrontPageText] = useState(''); const [altHome, setAltHome] = useState(''); const [baseColor, setBaseColor] = useState(''); const [logoFile, setLogoFile] = useState(null); @@ -23,30 +22,39 @@ export default function Theme() { const token = useSelector(state => state.user.token); useEffect(() => { - // Fetch theme data from localStorage or remote if needed fetchThemeData(); }, []); - const fetchThemeData = () => { + const fetchThemeData = async () => { setLoading(true); - const themeData = JSON.parse(localStorage.getItem('theme')) || {}; - setTheme(themeData); - setLoading(false); - }; - - useEffect(() => { - if (theme) { - setInstanceName(theme.instanceName || ''); - setFrontPageText(theme.frontPageText || ''); - setAltHome(theme.altHome || ''); + try { + const response = await axios.get(`${publicRuntimeConfig.backend}/admin/theme`, { + headers: { + Accept: 'application/json', + 'X-authorization': token + } + }); + const themeData = response.data; + updateThemeState(themeData); + localStorage.setItem('theme', JSON.stringify(themeData)); + } catch (error) { + console.error('Error fetching theme:', error); + const cachedTheme = JSON.parse(localStorage.getItem('theme')) || {}; + updateThemeState(cachedTheme); + } finally { + setLoading(false); } - }, [theme]); + }; - useEffect(() => { - if (theme && theme.themeParameters && theme.themeParameters[0]) { - setBaseColor(theme.themeParameters[0].value || ''); - } - }, [theme]); + const updateThemeState = (themeData) => { + setTheme(themeData); + setInstanceName(themeData.instanceName || ''); + setFrontPageText(themeData.frontPageText || ''); + setAltHome(themeData.altHome || ''); + setBaseColor(themeData.themeParameters?.[0]?.value || ''); + setShowModuleInteractions(themeData.showModuleInteractions ?? true); + setRemovePublicEnabled(themeData.removePublicEnabled ?? true); + }; const handleShowModuleInteractionsChange = (event) => { setShowModuleInteractions(event.target.checked); @@ -61,17 +69,12 @@ export default function Theme() { }; const handleSave = async () => { - const url = `${publicRuntimeConfig.backend}/admin/theme`; - const headers = { - Accept: 'text/plain', - 'X-authorization': token - }; - if (altHome !== '' && !isValidURI(altHome)) { alert('Alternate Home Page must be empty or contain a valid URL.'); - return; // Prevent form submission + return; } + setLoading(true); const formData = new FormData(); formData.append('instanceName', instanceName); formData.append('frontPageText', frontPageText); @@ -79,124 +82,132 @@ export default function Theme() { formData.append('baseColor', baseColor); formData.append('removePublicEnabled', removePublicEnabled); formData.append('showModuleInteractions', showModuleInteractions); - // if (logoFile) { - // formData.append('logo', logoFile); - // } + if (logoFile) { + formData.append('logo', logoFile); + } try { - const response = await fetch(url, { method: 'POST', headers, body: formData }); - console.log(response); - const data = await response.text(); + const response = await fetch(`${publicRuntimeConfig.backend}/admin/theme`, { + method: 'POST', + headers: { + Accept: 'text/plain', + 'X-authorization': token + }, + body: formData + }); if (response.ok) { - console.log(localStorage.getItem('theme')); - - console.log(data); - - if (data.requestBody) { - // Get the current theme from local storage - let currentTheme = JSON.parse(localStorage.getItem('theme')) || {}; - - // Update only the values that match and are different - Object.keys(data.requestBody).forEach(key => { - if (currentTheme[key] !== undefined && currentTheme[key] !== data.requestBody[key]) { - currentTheme[key] = data.requestBody[key]; - } - }); - - // Store the updated theme in local storage - localStorage.setItem('theme', JSON.stringify(currentTheme)); - console.log(localStorage); - } + // Create updated theme object + const updatedTheme = { + ...theme, + instanceName, + frontPageText, + altHome, + themeParameters: [{ value: baseColor }], + showModuleInteractions, + removePublicEnabled + }; + + // Update localStorage + localStorage.setItem('theme', JSON.stringify(updatedTheme)); + + // Update component state + updateThemeState(updatedTheme); + + alert('Theme saved successfully!'); + window.location.reload(); } else { - alert("Error saving theme"); + throw new Error('Failed to save theme'); } } catch (error) { - alert("Error saving theme"); + console.error('Error saving theme:', error); + alert('Error saving theme'); + } finally { + setLoading(false); } }; if (loading) return ; + return ( -
-
Logo
- setLogoFile(e.target.files[0])} /> -
Instance Name
- setInstanceName(e.target.value)} - style={{ width: '400px' }} - /> -
Front Page Description
-