diff --git a/frontend/src/App.js b/frontend/src/App.js
index 5b3a52b..2ba651a 100644
--- a/frontend/src/App.js
+++ b/frontend/src/App.js
@@ -3,19 +3,13 @@ import { MantineProvider, ColorSchemeScript } from '@mantine/core';
import { Notifications } from '@mantine/notifications';
import { ModalsProvider } from '@mantine/modals';
import Layout from './components/Layout';
-import { SettingsProvider, useSettings } from './contexts/SettingsContext';
+import { WorkspaceProvider } from './contexts/WorkspaceContext';
import { ModalProvider } from './contexts/ModalContext';
import '@mantine/core/styles.css';
import '@mantine/notifications/styles.css';
import './App.scss';
function AppContent() {
- const { loading } = useSettings();
-
- if (loading) {
- return
Loading...
;
- }
-
return ;
}
@@ -26,11 +20,11 @@ function App() {
-
+
-
+
>
diff --git a/frontend/src/components/Editor.js b/frontend/src/components/Editor.js
index 1491f8e..91dd89f 100644
--- a/frontend/src/components/Editor.js
+++ b/frontend/src/components/Editor.js
@@ -5,10 +5,10 @@ import { EditorView, keymap } from '@codemirror/view';
import { markdown } from '@codemirror/lang-markdown';
import { defaultKeymap } from '@codemirror/commands';
import { oneDark } from '@codemirror/theme-one-dark';
-import { useSettings } from '../contexts/SettingsContext';
+import { useWorkspace } from '../contexts/WorkspaceContext';
const Editor = ({ content, handleContentChange, handleSave, selectedFile }) => {
- const { settings } = useSettings();
+ const { settings } = useWorkspace();
const editorRef = useRef();
const viewRef = useRef();
diff --git a/frontend/src/components/FileActions.js b/frontend/src/components/FileActions.js
index 5984a89..b387022 100644
--- a/frontend/src/components/FileActions.js
+++ b/frontend/src/components/FileActions.js
@@ -6,11 +6,11 @@ import {
IconGitPullRequest,
IconGitCommit,
} from '@tabler/icons-react';
-import { useSettings } from '../contexts/SettingsContext';
import { useModalContext } from '../contexts/ModalContext';
+import { useWorkspace } from '../contexts/WorkspaceContext';
const FileActions = ({ handlePullChanges, selectedFile }) => {
- const { settings } = useSettings();
+ const { settings } = useWorkspace();
const {
setNewFileModalVisible,
setDeleteFileModalVisible,
diff --git a/frontend/src/components/Layout.js b/frontend/src/components/Layout.js
index 97df9e8..ef012f2 100644
--- a/frontend/src/components/Layout.js
+++ b/frontend/src/components/Layout.js
@@ -1,16 +1,30 @@
import React from 'react';
-import { AppShell, Container } from '@mantine/core';
+import { AppShell, Container, Loader, Center } from '@mantine/core';
import Header from './Header';
import Sidebar from './Sidebar';
import MainContent from './MainContent';
import { useFileNavigation } from '../hooks/useFileNavigation';
import { useFileList } from '../hooks/useFileList';
+import { useWorkspace } from '../contexts/WorkspaceContext';
const Layout = () => {
+ const { currentWorkspace, loading: workspaceLoading } = useWorkspace();
const { selectedFile, handleFileSelect, handleLinkClick } =
useFileNavigation();
const { files, loadFileList } = useFileList();
+ if (workspaceLoading) {
+ return (
+
+
+
+ );
+ }
+
+ if (!currentWorkspace) {
+ return No workspace found. Please create a workspace.
;
+ }
+
return (
@@ -22,8 +36,8 @@ const Layout = () => {
p={0}
style={{
display: 'flex',
- height: 'calc(100vh - 60px - 2rem)', // Subtracting header height and vertical padding
- overflow: 'hidden', // Prevent scrolling in the container
+ height: 'calc(100vh - 60px - 2rem)',
+ overflow: 'hidden',
}}
>
{
const [activeTab, setActiveTab] = useState('source');
- const { settings } = useSettings();
+ const { settings } = useWorkspace();
const {
content,
hasUnsavedChanges,
diff --git a/frontend/src/components/Settings.js b/frontend/src/components/Settings.js
index b0e10ce..7526254 100644
--- a/frontend/src/components/Settings.js
+++ b/frontend/src/components/Settings.js
@@ -1,7 +1,7 @@
import React, { useReducer, useEffect, useCallback, useRef } from 'react';
import { Modal, Badge, Button, Group, Title } from '@mantine/core';
import { notifications } from '@mantine/notifications';
-import { useSettings } from '../contexts/SettingsContext';
+import { useWorkspace } from '../contexts/WorkspaceContext';
import AppearanceSettings from './settings/AppearanceSettings';
import EditorSettings from './settings/EditorSettings';
import GitSettings from './settings/GitSettings';
@@ -50,7 +50,7 @@ function settingsReducer(state, action) {
}
const Settings = () => {
- const { settings, updateSettings, colorScheme } = useSettings();
+ const { settings, updateSettings, colorScheme } = useWorkspace();
const { settingsModalVisible, setSettingsModalVisible } = useModalContext();
const [state, dispatch] = useReducer(settingsReducer, initialState);
const isInitialMount = useRef(true);
diff --git a/frontend/src/components/Sidebar.js b/frontend/src/components/Sidebar.js
index 79271f7..04619c7 100644
--- a/frontend/src/components/Sidebar.js
+++ b/frontend/src/components/Sidebar.js
@@ -3,10 +3,10 @@ import { Box } from '@mantine/core';
import FileActions from './FileActions';
import FileTree from './FileTree';
import { useGitOperations } from '../hooks/useGitOperations';
-import { useSettings } from '../contexts/SettingsContext';
+import { useWorkspace } from '../contexts/WorkspaceContext';
const Sidebar = ({ selectedFile, handleFileSelect, files, loadFileList }) => {
- const { settings } = useSettings();
+ const { settings } = useWorkspace();
const { handlePull } = useGitOperations(settings.gitEnabled);
useEffect(() => {
diff --git a/frontend/src/components/settings/AppearanceSettings.js b/frontend/src/components/settings/AppearanceSettings.js
index f29f253..2073c4f 100644
--- a/frontend/src/components/settings/AppearanceSettings.js
+++ b/frontend/src/components/settings/AppearanceSettings.js
@@ -1,9 +1,9 @@
import React from 'react';
import { Text, Switch, Group, Box, Title } from '@mantine/core';
-import { useSettings } from '../../contexts/SettingsContext';
+import { useWorkspace } from '../../contexts/WorkspaceContext';
const AppearanceSettings = ({ onThemeChange }) => {
- const { colorScheme, toggleColorScheme } = useSettings();
+ const { colorScheme, toggleColorScheme } = useWorkspace();
const handleThemeChange = () => {
toggleColorScheme();
diff --git a/frontend/src/contexts/SettingsContext.js b/frontend/src/contexts/SettingsContext.js
deleted file mode 100644
index 0a8df8d..0000000
--- a/frontend/src/contexts/SettingsContext.js
+++ /dev/null
@@ -1,79 +0,0 @@
-import React, {
- createContext,
- useContext,
- useEffect,
- useMemo,
- useCallback,
- useState,
-} from 'react';
-import { useMantineColorScheme } from '@mantine/core';
-import { fetchUserSettings, saveUserSettings } from '../services/api';
-import { DEFAULT_SETTINGS } from '../utils/constants';
-
-const SettingsContext = createContext();
-
-export const useSettings = () => useContext(SettingsContext);
-
-export const SettingsProvider = ({ children }) => {
- const { colorScheme, setColorScheme } = useMantineColorScheme();
- const [settings, setSettings] = useState(DEFAULT_SETTINGS);
- const [loading, setLoading] = useState(true);
-
- useEffect(() => {
- const loadSettings = async () => {
- try {
- const userSettings = await fetchUserSettings(1);
- setSettings(userSettings.settings);
- setColorScheme(userSettings.settings.theme);
- } catch (error) {
- console.error('Failed to load user settings:', error);
- } finally {
- setLoading(false);
- }
- };
-
- loadSettings();
- }, []);
-
- const updateSettings = useCallback(
- async (newSettings) => {
- try {
- await saveUserSettings({
- userId: 1,
- settings: newSettings,
- });
- setSettings(newSettings);
- if (newSettings.theme) {
- setColorScheme(newSettings.theme);
- }
- } catch (error) {
- console.error('Failed to save settings:', error);
- throw error;
- }
- },
- [setColorScheme]
- );
-
- const toggleColorScheme = useCallback(() => {
- const newTheme = colorScheme === 'dark' ? 'light' : 'dark';
- setColorScheme(newTheme);
- updateSettings({ ...settings, theme: newTheme });
- }, [colorScheme, settings, setColorScheme, updateSettings]);
-
- const contextValue = useMemo(
- () => ({
- settings,
- updateSettings,
- toggleColorScheme,
- loading,
- colorScheme,
- }),
- [settings, updateSettings, toggleColorScheme, loading, colorScheme]
- );
-
- return (
-
- {children}
-
- );
-};
diff --git a/frontend/src/contexts/WorkspaceContext.js b/frontend/src/contexts/WorkspaceContext.js
new file mode 100644
index 0000000..41b4e46
--- /dev/null
+++ b/frontend/src/contexts/WorkspaceContext.js
@@ -0,0 +1,92 @@
+import React, {
+ createContext,
+ useContext,
+ useState,
+ useEffect,
+ useCallback,
+} from 'react';
+import { useMantineColorScheme } from '@mantine/core';
+import {
+ fetchLastWorkspace,
+ fetchWorkspaceSettings,
+ saveWorkspaceSettings,
+} from '../services/api';
+import { DEFAULT_SETTINGS } from '../utils/constants';
+
+const WorkspaceContext = createContext();
+
+export const WorkspaceProvider = ({ children }) => {
+ const [currentWorkspace, setCurrentWorkspace] = useState(null);
+ const [settings, setSettings] = useState(DEFAULT_SETTINGS);
+ const [loading, setLoading] = useState(true);
+ const { colorScheme, setColorScheme } = useMantineColorScheme();
+
+ useEffect(() => {
+ const loadWorkspaceAndSettings = async () => {
+ try {
+ const workspace = await fetchLastWorkspace();
+ setCurrentWorkspace(workspace);
+
+ if (workspace) {
+ const workspaceSettings = await fetchWorkspaceSettings(workspace.id);
+ setSettings(workspaceSettings.settings);
+ setColorScheme(workspaceSettings.settings.theme);
+ }
+ } catch (error) {
+ console.error('Failed to load workspace or settings:', error);
+ } finally {
+ setLoading(false);
+ }
+ };
+
+ loadWorkspaceAndSettings();
+ }, [setColorScheme]);
+
+ const updateSettings = useCallback(
+ async (newSettings) => {
+ if (!currentWorkspace) return;
+
+ try {
+ await saveWorkspaceSettings(currentWorkspace.id, newSettings);
+ setSettings(newSettings);
+ if (newSettings.theme) {
+ setColorScheme(newSettings.theme);
+ }
+ } catch (error) {
+ console.error('Failed to save settings:', error);
+ throw error;
+ }
+ },
+ [currentWorkspace, setColorScheme]
+ );
+
+ const toggleColorScheme = useCallback(() => {
+ const newTheme = colorScheme === 'dark' ? 'light' : 'dark';
+ setColorScheme(newTheme);
+ updateSettings({ ...settings, theme: newTheme });
+ }, [colorScheme, settings, setColorScheme, updateSettings]);
+
+ const value = {
+ currentWorkspace,
+ setCurrentWorkspace,
+ settings,
+ updateSettings,
+ toggleColorScheme,
+ loading,
+ colorScheme,
+ };
+
+ return (
+
+ {children}
+
+ );
+};
+
+export const useWorkspace = () => {
+ const context = useContext(WorkspaceContext);
+ if (context === undefined) {
+ throw new Error('useWorkspace must be used within a WorkspaceProvider');
+ }
+ return context;
+};
diff --git a/frontend/src/hooks/useFileContent.js b/frontend/src/hooks/useFileContent.js
index ba12b22..cb304d0 100644
--- a/frontend/src/hooks/useFileContent.js
+++ b/frontend/src/hooks/useFileContent.js
@@ -2,38 +2,45 @@ import { useState, useCallback, useEffect } from 'react';
import { fetchFileContent } from '../services/api';
import { isImageFile } from '../utils/fileHelpers';
import { DEFAULT_FILE } from '../utils/constants';
+import { useWorkspace } from '../contexts/WorkspaceContext';
export const useFileContent = (selectedFile) => {
+ const { currentWorkspace } = useWorkspace();
const [content, setContent] = useState(DEFAULT_FILE.content);
const [originalContent, setOriginalContent] = useState(DEFAULT_FILE.content);
const [hasUnsavedChanges, setHasUnsavedChanges] = useState(false);
- const loadFileContent = useCallback(async (filePath) => {
- try {
- let newContent;
- if (filePath === DEFAULT_FILE.path) {
- newContent = DEFAULT_FILE.content;
- } else if (!isImageFile(filePath)) {
- newContent = await fetchFileContent(filePath);
- } else {
- newContent = ''; // Set empty content for image files
+ const loadFileContent = useCallback(
+ async (filePath) => {
+ if (!currentWorkspace) return;
+
+ try {
+ let newContent;
+ if (filePath === DEFAULT_FILE.path) {
+ newContent = DEFAULT_FILE.content;
+ } else if (!isImageFile(filePath)) {
+ newContent = await fetchFileContent(currentWorkspace.id, filePath);
+ } else {
+ newContent = ''; // Set empty content for image files
+ }
+ setContent(newContent);
+ setOriginalContent(newContent);
+ setHasUnsavedChanges(false);
+ } catch (err) {
+ console.error('Error loading file content:', err);
+ setContent(''); // Set empty content on error
+ setOriginalContent('');
+ setHasUnsavedChanges(false);
}
- setContent(newContent);
- setOriginalContent(newContent);
- setHasUnsavedChanges(false);
- } catch (err) {
- console.error('Error loading file content:', err);
- setContent(''); // Set empty content on error
- setOriginalContent('');
- setHasUnsavedChanges(false);
- }
- }, []);
+ },
+ [currentWorkspace]
+ );
useEffect(() => {
- if (selectedFile) {
+ if (selectedFile && currentWorkspace) {
loadFileContent(selectedFile);
}
- }, [selectedFile, loadFileContent]);
+ }, [selectedFile, currentWorkspace, loadFileContent]);
const handleContentChange = useCallback(
(newContent) => {
diff --git a/frontend/src/hooks/useFileList.js b/frontend/src/hooks/useFileList.js
index 2e8abed..36171a8 100644
--- a/frontend/src/hooks/useFileList.js
+++ b/frontend/src/hooks/useFileList.js
@@ -1,12 +1,16 @@
import { useState, useCallback } from 'react';
import { fetchFileList } from '../services/api';
+import { useWorkspace } from '../contexts/WorkspaceContext';
export const useFileList = () => {
const [files, setFiles] = useState([]);
+ const { currentWorkspace } = useWorkspace();
const loadFileList = useCallback(async () => {
+ if (!currentWorkspace) return;
+
try {
- const fileList = await fetchFileList();
+ const fileList = await fetchFileList(currentWorkspace.id);
if (Array.isArray(fileList)) {
setFiles(fileList);
} else {
@@ -15,7 +19,7 @@ export const useFileList = () => {
} catch (error) {
console.error('Failed to load file list:', error);
}
- }, []);
+ }, [currentWorkspace]);
return { files, loadFileList };
};
diff --git a/frontend/src/hooks/useFileNavigation.js b/frontend/src/hooks/useFileNavigation.js
index 497f1e4..7c3623d 100644
--- a/frontend/src/hooks/useFileNavigation.js
+++ b/frontend/src/hooks/useFileNavigation.js
@@ -2,10 +2,12 @@ import { useState, useCallback } from 'react';
import { notifications } from '@mantine/notifications';
import { lookupFileByName } from '../services/api';
import { DEFAULT_FILE } from '../utils/constants';
+import { useWorkspace } from '../contexts/WorkspaceContext';
export const useFileNavigation = () => {
const [selectedFile, setSelectedFile] = useState(DEFAULT_FILE.path);
const [isNewFile, setIsNewFile] = useState(true);
+ const { currentWorkspace } = useWorkspace();
const handleFileSelect = useCallback((filePath) => {
setSelectedFile(filePath);
@@ -14,8 +16,10 @@ export const useFileNavigation = () => {
const handleLinkClick = useCallback(
async (filename) => {
+ if (!currentWorkspace) return;
+
try {
- const filePaths = await lookupFileByName(filename);
+ const filePaths = await lookupFileByName(currentWorkspace.id, filename);
if (filePaths.length >= 1) {
handleFileSelect(filePaths[0]);
} else {
@@ -34,7 +38,7 @@ export const useFileNavigation = () => {
});
}
},
- [handleFileSelect]
+ [currentWorkspace, handleFileSelect]
);
return { handleLinkClick, selectedFile, isNewFile, handleFileSelect };
diff --git a/frontend/src/hooks/useFileOperations.js b/frontend/src/hooks/useFileOperations.js
index a76b5b4..4b7f70a 100644
--- a/frontend/src/hooks/useFileOperations.js
+++ b/frontend/src/hooks/useFileOperations.js
@@ -1,12 +1,12 @@
import { useCallback } from 'react';
import { notifications } from '@mantine/notifications';
import { saveFileContent, deleteFile } from '../services/api';
-import { useSettings } from '../contexts/SettingsContext';
+import { useWorkspace } from '../contexts/WorkspaceContext';
import { useGitOperations } from './useGitOperations';
export const useFileOperations = () => {
- const { settings } = useSettings();
- const { handleCommitAndPush } = useGitOperations(settings.gitEnabled);
+ const { currentWorkspace, settings } = useWorkspace();
+ const { handleCommitAndPush } = useGitOperations();
const autoCommit = useCallback(
async (filePath, action) => {
@@ -15,7 +15,6 @@ export const useFileOperations = () => {
.replace('${filename}', filePath)
.replace('${action}', action);
- // Capitalize the first letter of the commit message
commitMessage =
commitMessage.charAt(0).toUpperCase() + commitMessage.slice(1);
@@ -27,8 +26,10 @@ export const useFileOperations = () => {
const handleSave = useCallback(
async (filePath, content) => {
+ if (!currentWorkspace) return false;
+
try {
- await saveFileContent(filePath, content);
+ await saveFileContent(currentWorkspace.id, filePath, content);
notifications.show({
title: 'Success',
message: 'File saved successfully',
@@ -46,13 +47,15 @@ export const useFileOperations = () => {
return false;
}
},
- [autoCommit]
+ [currentWorkspace, autoCommit]
);
const handleDelete = useCallback(
async (filePath) => {
+ if (!currentWorkspace) return false;
+
try {
- await deleteFile(filePath);
+ await deleteFile(currentWorkspace.id, filePath);
notifications.show({
title: 'Success',
message: 'File deleted successfully',
@@ -70,13 +73,15 @@ export const useFileOperations = () => {
return false;
}
},
- [autoCommit]
+ [currentWorkspace, autoCommit]
);
const handleCreate = useCallback(
async (fileName, initialContent = '') => {
+ if (!currentWorkspace) return false;
+
try {
- await saveFileContent(fileName, initialContent);
+ await saveFileContent(currentWorkspace.id, fileName, initialContent);
notifications.show({
title: 'Success',
message: 'File created successfully',
@@ -94,7 +99,7 @@ export const useFileOperations = () => {
return false;
}
},
- [autoCommit]
+ [currentWorkspace, autoCommit]
);
return { handleSave, handleDelete, handleCreate };
diff --git a/frontend/src/hooks/useGitOperations.js b/frontend/src/hooks/useGitOperations.js
index 63f2424..40e1669 100644
--- a/frontend/src/hooks/useGitOperations.js
+++ b/frontend/src/hooks/useGitOperations.js
@@ -1,12 +1,16 @@
import { useCallback } from 'react';
import { notifications } from '@mantine/notifications';
import { pullChanges, commitAndPush } from '../services/api';
+import { useWorkspace } from '../contexts/WorkspaceContext';
+
+export const useGitOperations = () => {
+ const { currentWorkspace, settings } = useWorkspace();
-export const useGitOperations = (gitEnabled) => {
const handlePull = useCallback(async () => {
- if (!gitEnabled) return false;
+ if (!currentWorkspace || !settings.gitEnabled) return false;
+
try {
- await pullChanges();
+ await pullChanges(currentWorkspace.id);
notifications.show({
title: 'Success',
message: 'Successfully pulled latest changes',
@@ -22,13 +26,14 @@ export const useGitOperations = (gitEnabled) => {
});
return false;
}
- }, [gitEnabled]);
+ }, [currentWorkspace, settings.gitEnabled]);
const handleCommitAndPush = useCallback(
async (message) => {
- if (!gitEnabled) return false;
+ if (!currentWorkspace || !settings.gitEnabled) return false;
+
try {
- await commitAndPush(message);
+ await commitAndPush(currentWorkspace.id, message);
notifications.show({
title: 'Success',
message: 'Successfully committed and pushed changes',
@@ -45,7 +50,7 @@ export const useGitOperations = (gitEnabled) => {
return false;
}
},
- [gitEnabled]
+ [currentWorkspace, settings.gitEnabled]
);
return { handlePull, handleCommitAndPush };
diff --git a/frontend/src/services/api.js b/frontend/src/services/api.js
index 8b57ad5..66c1cad 100644
--- a/frontend/src/services/api.js
+++ b/frontend/src/services/api.js
@@ -16,76 +16,176 @@ const apiCall = async (url, options = {}) => {
}
};
-export const fetchFileList = async () => {
- const response = await apiCall(`${API_BASE_URL}/files`);
+export const fetchLastWorkspace = async () => {
+ const response = await apiCall(`${API_BASE_URL}/users/1/workspaces/last`);
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 () => {
- const response = await apiCall(`${API_BASE_URL}/git/pull`, {
- method: 'POST',
- });
- return response.json();
-};
-
-export const commitAndPush = async (message) => {
- 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) => {
- return `${API_BASE_URL}/files/${filePath}`;
-};
-
-export const lookupFileByName = async (filename) => {
+export const fetchFileList = async (workspaceId) => {
const response = await apiCall(
- `${API_BASE_URL}/files/lookup?filename=${encodeURIComponent(filename)}`
+ `${API_BASE_URL}/users/1/workspaces/${workspaceId}/files`
+ );
+ return response.json();
+};
+
+export const fetchFileContent = async (workspaceId, filePath) => {
+ const response = await apiCall(
+ `${API_BASE_URL}/users/1/workspaces/${workspaceId}/files/${filePath}`
+ );
+ return response.text();
+};
+
+export const saveFileContent = async (workspaceId, filePath, content) => {
+ const response = await apiCall(
+ `${API_BASE_URL}/users/1/workspaces/${workspaceId}/files/${filePath}`,
+ {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'text/plain',
+ },
+ body: content,
+ }
+ );
+ return response.text();
+};
+
+export const deleteFile = async (workspaceId, filePath) => {
+ const response = await apiCall(
+ `${API_BASE_URL}/users/1/workspaces/${workspaceId}/files/${filePath}`,
+ {
+ method: 'DELETE',
+ }
+ );
+ return response.text();
+};
+
+export const fetchWorkspaceSettings = async (workspaceId) => {
+ const response = await apiCall(
+ `${API_BASE_URL}/users/1/workspaces/${workspaceId}/settings`
+ );
+ return response.json();
+};
+
+export const saveWorkspaceSettings = async (workspaceId, settings) => {
+ const response = await apiCall(
+ `${API_BASE_URL}/users/1/workspaces/${workspaceId}/settings`,
+ {
+ method: 'PUT',
+ headers: {
+ 'Content-Type': 'application/json',
+ },
+ body: JSON.stringify({ settings }),
+ }
+ );
+ return response.json();
+};
+
+export const pullChanges = async (workspaceId) => {
+ const response = await apiCall(
+ `${API_BASE_URL}/users/1/workspaces/${workspaceId}/git/pull`,
+ {
+ method: 'POST',
+ }
+ );
+ return response.json();
+};
+
+export const commitAndPush = async (workspaceId, message) => {
+ const response = await apiCall(
+ `${API_BASE_URL}/users/1/workspaces/${workspaceId}/git/commit`,
+ {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json',
+ },
+ body: JSON.stringify({ message }),
+ }
+ );
+ return response.json();
+};
+
+export const getFileUrl = (workspaceId, filePath) => {
+ return `${API_BASE_URL}/users/1/workspaces/${workspaceId}/files/${filePath}`;
+};
+
+export const lookupFileByName = async (workspaceId, filename) => {
+ const response = await apiCall(
+ `${API_BASE_URL}/users/1/workspaces/${workspaceId}/files/lookup?filename=${encodeURIComponent(
+ filename
+ )}`
);
const data = await response.json();
return data.paths;
};
+
+export const updateLastOpenedFile = async (workspaceId, filePath) => {
+ const response = await apiCall(
+ `${API_BASE_URL}/users/1/workspaces/${workspaceId}/files/last`,
+ {
+ method: 'PUT',
+ headers: {
+ 'Content-Type': 'application/json',
+ },
+ body: JSON.stringify({ filePath }),
+ }
+ );
+ return response.json();
+};
+
+export const getLastOpenedFile = async (workspaceId) => {
+ const response = await apiCall(
+ `${API_BASE_URL}/users/1/workspaces/${workspaceId}/files/last`
+ );
+ return response.json();
+};
+
+export const listWorkspaces = async () => {
+ const response = await apiCall(`${API_BASE_URL}/users/1/workspaces`);
+ return response.json();
+};
+
+export const createWorkspace = async (name) => {
+ const response = await apiCall(`${API_BASE_URL}/users/1/workspaces`, {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json',
+ },
+ body: JSON.stringify({ name }),
+ });
+ return response.json();
+};
+
+export const updateWorkspace = async (workspaceId, name) => {
+ const response = await apiCall(
+ `${API_BASE_URL}/users/1/workspaces/${workspaceId}`,
+ {
+ method: 'PUT',
+ headers: {
+ 'Content-Type': 'application/json',
+ },
+ body: JSON.stringify({ name }),
+ }
+ );
+ return response.json();
+};
+
+export const deleteWorkspace = async (workspaceId) => {
+ const response = await apiCall(
+ `${API_BASE_URL}/users/1/workspaces/${workspaceId}`,
+ {
+ method: 'DELETE',
+ }
+ );
+ return response.json();
+};
+
+export const updateLastWorkspace = async (workspaceId) => {
+ const response = await apiCall(`${API_BASE_URL}/users/1/workspaces/last`, {
+ method: 'PUT',
+ headers: {
+ 'Content-Type': 'application/json',
+ },
+ body: JSON.stringify({ workspaceId }),
+ });
+ return response.json();
+};