diff --git a/frontend/src/App.js b/frontend/src/App.js index 8e4f5ff..7c8dad0 100644 --- a/frontend/src/App.js +++ b/frontend/src/App.js @@ -40,7 +40,7 @@ function App() { lookupFileByName, } = useFileManagement(settings.gitEnabled); - const setTheme = (newTheme) => { + const handleThemeChange = (newTheme) => { setThemeType(newTheme); }; @@ -68,7 +68,7 @@ function App() { -
+
{ - const imageExtensions = ['.jpg', '.jpeg', '.png', '.gif', '.webp', '.svg']; - return imageExtensions.some((ext) => fileName.toLowerCase().endsWith(ext)); - }; - const renderIcon = ({ type, name }) => { if (type === 'directory') return ; return isImageFile(name) ? : ; diff --git a/frontend/src/components/MainContent.js b/frontend/src/components/MainContent.js index 53fe002..01ac0d9 100644 --- a/frontend/src/components/MainContent.js +++ b/frontend/src/components/MainContent.js @@ -21,11 +21,7 @@ import { getFileUrl, lookupFileByName, } from '../services/api'; - -const isImageFile = (filePath) => { - const imageExtensions = ['.jpg', '.jpeg', '.png', '.gif', '.webp', '.svg']; - return imageExtensions.some((ext) => filePath.toLowerCase().endsWith(ext)); -}; +import { isImageFile } from '../utils/fileHelpers'; const MainContent = ({ content, @@ -37,7 +33,7 @@ const MainContent = ({ onContentChange, onSave, settings, - pullLatestChanges, + onPullLatestChanges, onLinkClick, }) => { const [activeTab, setActiveTab] = useState('source'); @@ -63,7 +59,7 @@ const MainContent = ({ const handlePull = async () => { try { - await pullLatestChanges(); + await onPullLatestChanges(); setToast({ text: 'Successfully pulled latest changes', type: 'success' }); } catch (error) { setToast({ @@ -82,7 +78,7 @@ const MainContent = ({ text: 'Changes committed and pushed successfully', type: 'success', }); - await pullLatestChanges(); // Pull changes after successful push + await onPullLatestChanges(); // Pull changes after successful push } } catch (error) { setToast({ @@ -101,7 +97,7 @@ const MainContent = ({ try { await saveFileContent(newFileName, ''); setToast({ text: 'New file created successfully', type: 'success' }); - await pullLatestChanges(); // Refresh file list + await onPullLatestChanges(); // Refresh file list onFileSelect(newFileName); // Select the new file } catch (error) { setToast({ @@ -123,7 +119,7 @@ const MainContent = ({ try { await deleteFile(selectedFile); setToast({ text: 'File deleted successfully', type: 'success' }); - await pullLatestChanges(); // Refresh file list + await onPullLatestChanges(); // Refresh file list onFileSelect(null); // Deselect the file } catch (error) { setToast({ diff --git a/frontend/src/hooks/useFileManagement.js b/frontend/src/hooks/useFileManagement.js index 8e78d6e..6d7ccaf 100644 --- a/frontend/src/hooks/useFileManagement.js +++ b/frontend/src/hooks/useFileManagement.js @@ -7,6 +7,7 @@ import { pullChanges, lookupFileByName, } from '../services/api'; +import { isImageFile } from '../utils/fileHelpers'; const DEFAULT_FILE = { name: 'New File.md', @@ -14,11 +15,6 @@ const DEFAULT_FILE = { content: '# Welcome to NovaMD\n\nStart editing here!', }; -const isImageFile = (filePath) => { - const imageExtensions = ['.jpg', '.jpeg', '.png', '.gif', '.webp', '.svg']; - return imageExtensions.some((ext) => filePath.toLowerCase().endsWith(ext)); -}; - const useFileManagement = (gitEnabled = false) => { const [content, setContent] = useState(DEFAULT_FILE.content); const [files, setFiles] = useState([]); diff --git a/frontend/src/services/api.js b/frontend/src/services/api.js index 108e9e3..8b57ad5 100644 --- a/frontend/src/services/api.js +++ b/frontend/src/services/api.js @@ -1,131 +1,81 @@ const API_BASE_URL = window.API_BASE_URL; -export const fetchFileList = async () => { +const apiCall = async (url, options = {}) => { try { - const response = await fetch(`${API_BASE_URL}/files`); - if (!response.ok) { - throw new Error('Failed to fetch file list'); - } - return await response.json(); - } catch (error) { - console.error('Error fetching file list:', error); - throw error; - } -}; - -export const fetchFileContent = async (filePath) => { - try { - const response = await fetch(`${API_BASE_URL}/files/${filePath}`); - if (!response.ok) { - throw new Error('Failed to fetch file content'); - } - return await response.text(); - } catch (error) { - console.error('Error fetching file content:', error); - throw error; - } -}; - -export const saveFileContent = async (filePath, content) => { - const response = await fetch(`${API_BASE_URL}/files/${filePath}`, { - method: 'POST', - headers: { - 'Content-Type': 'text/plain', - }, - body: content, - }); - - if (!response.ok) { - throw new Error('Failed to save file'); - } - - return await response.text(); -}; - -export const deleteFile = async (filePath) => { - try { - const response = await fetch(`${API_BASE_URL}/files/${filePath}`, { - method: 'DELETE', - }); - if (!response.ok) { - throw new Error('Failed to delete file'); - } - return await response.text(); - } catch (error) { - console.error('Error deleting file:', error); - throw error; - } -}; - -export const fetchUserSettings = async (userId) => { - try { - const response = await fetch(`${API_BASE_URL}/settings?userId=${userId}`); - if (!response.ok) { - throw new Error('Failed to fetch user settings'); - } - return await response.json(); - } catch (error) { - console.error('Error fetching user settings:', error); - throw error; - } -}; - -export const saveUserSettings = async (settings) => { - try { - const response = await fetch(`${API_BASE_URL}/settings`, { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - }, - body: JSON.stringify(settings), - }); - + const response = await fetch(url, options); if (!response.ok) { const errorData = await response.json().catch(() => null); throw new Error( errorData?.message || `HTTP error! status: ${response.status}` ); } - - return await response.json(); + return response; } catch (error) { - console.error('Error saving user settings:', error); + console.error(`API call failed: ${error.message}`); throw error; } }; +export const fetchFileList = async () => { + const response = await apiCall(`${API_BASE_URL}/files`); + return response.json(); +}; + +export const fetchFileContent = async (filePath) => { + const response = await apiCall(`${API_BASE_URL}/files/${filePath}`); + return response.text(); +}; + +export const saveFileContent = async (filePath, content) => { + const response = await apiCall(`${API_BASE_URL}/files/${filePath}`, { + method: 'POST', + headers: { + 'Content-Type': 'text/plain', + }, + body: content, + }); + return response.text(); +}; + +export const deleteFile = async (filePath) => { + const response = await apiCall(`${API_BASE_URL}/files/${filePath}`, { + method: 'DELETE', + }); + return response.text(); +}; + +export const fetchUserSettings = async (userId) => { + const response = await apiCall(`${API_BASE_URL}/settings?userId=${userId}`); + return response.json(); +}; + +export const saveUserSettings = async (settings) => { + const response = await apiCall(`${API_BASE_URL}/settings`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify(settings), + }); + return response.json(); +}; + export const pullChanges = async () => { - try { - const response = await fetch(`${API_BASE_URL}/git/pull`, { - method: 'POST', - }); - if (!response.ok) { - throw new Error('Failed to pull changes'); - } - return await response.json(); - } catch (error) { - console.error('Error pulling changes:', error); - throw error; - } + const response = await apiCall(`${API_BASE_URL}/git/pull`, { + method: 'POST', + }); + return response.json(); }; export const commitAndPush = async (message) => { - try { - const response = await fetch(`${API_BASE_URL}/git/commit`, { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - }, - body: JSON.stringify({ message }), - }); - if (!response.ok) { - throw new Error('Failed to commit and push changes'); - } - return await response.json(); - } catch (error) { - console.error('Error committing and pushing changes:', error); - throw error; - } + const response = await apiCall(`${API_BASE_URL}/git/commit`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ message }), + }); + return response.json(); }; export const getFileUrl = (filePath) => { @@ -133,17 +83,9 @@ export const getFileUrl = (filePath) => { }; export const lookupFileByName = async (filename) => { - try { - const response = await fetch( - `${API_BASE_URL}/files/lookup?filename=${encodeURIComponent(filename)}` - ); - if (!response.ok) { - throw new Error('File not found'); - } - const data = await response.json(); - return data.paths; - } catch (error) { - console.error('Error looking up file:', error); - throw error; - } + const response = await apiCall( + `${API_BASE_URL}/files/lookup?filename=${encodeURIComponent(filename)}` + ); + const data = await response.json(); + return data.paths; }; diff --git a/frontend/src/utils/fileHelpers.js b/frontend/src/utils/fileHelpers.js new file mode 100644 index 0000000..f2e95a5 --- /dev/null +++ b/frontend/src/utils/fileHelpers.js @@ -0,0 +1,4 @@ +export const isImageFile = (filePath) => { + const imageExtensions = ['.jpg', '.jpeg', '.png', '.gif', '.webp', '.svg']; + return imageExtensions.some((ext) => filePath.toLowerCase().endsWith(ext)); +};