Save file on FE

This commit is contained in:
2024-09-26 15:43:28 +02:00
parent 9faa212043
commit fcbf4a689f
3 changed files with 50 additions and 7 deletions

View File

@@ -1,8 +1,8 @@
import React, { useState, useEffect } from 'react';
import { GeistProvider, CssBaseline } from '@geist-ui/core';
import React, { useState, useEffect, useCallback } from 'react';
import { GeistProvider, CssBaseline, useToasts } from '@geist-ui/core';
import Editor from './components/Editor';
import FileTree from './components/FileTree';
import { fetchFileList, fetchFileContent } from './services/api';
import { fetchFileList, fetchFileContent, saveFileContent } from './services/api';
import './App.scss';
function App() {
@@ -10,6 +10,7 @@ function App() {
const [files, setFiles] = useState([]);
const [selectedFile, setSelectedFile] = useState(null);
const [error, setError] = useState(null);
const { setToast } = useToasts();
useEffect(() => {
const loadFileList = async () => {
@@ -34,12 +35,23 @@ function App() {
const fileContent = await fetchFileContent(filePath);
setContent(fileContent);
setSelectedFile(filePath);
setError(null);
} catch (error) {
console.error('Failed to load file content:', error);
setError('Failed to load file content. Please try again.');
}
};
const handleSave = useCallback(async (filePath, fileContent) => {
try {
await saveFileContent(filePath, fileContent);
setToast({ text: 'File saved successfully', type: 'success' });
} catch (error) {
console.error('Error saving file:', error);
setToast({ text: 'Failed to save file. Please try again.', type: 'error' });
}
}, [setToast]);
return (
<GeistProvider>
<CssBaseline />
@@ -57,7 +69,12 @@ function App() {
</div>
<div className="main-content">
<h1>NovaMD</h1>
<Editor content={content} onChange={setContent} />
<Editor
content={content}
onChange={setContent}
onSave={handleSave}
filePath={selectedFile}
/>
</div>
</div>
</GeistProvider>

View File

@@ -5,17 +5,27 @@ import { EditorView, keymap } from "@codemirror/view";
import { markdown } from "@codemirror/lang-markdown";
import { defaultKeymap } from "@codemirror/commands";
const Editor = ({ content, onChange }) => {
const Editor = ({ content, onChange, onSave, filePath }) => {
const editorRef = useRef();
const viewRef = useRef();
useEffect(() => {
const handleSave = (view) => {
onSave(filePath, view.state.doc.toString());
return true;
};
const state = EditorState.create({
doc: content,
extensions: [
basicSetup,
markdown(),
keymap.of(defaultKeymap),
keymap.of([{
key: "Ctrl-s",
run: handleSave,
preventDefault: true
}]),
EditorView.updateListener.of((update) => {
if (update.docChanged) {
onChange(update.state.doc.toString());
@@ -34,7 +44,7 @@ const Editor = ({ content, onChange }) => {
return () => {
view.destroy();
};
}, []);
}, [filePath]);
useEffect(() => {
if (viewRef.current && content !== viewRef.current.state.doc.toString()) {

View File

@@ -24,4 +24,20 @@ export const fetchFileContent = async (filePath) => {
console.error('Error fetching file content:', error);
throw error;
}
};
};
export const saveFileContent = async (filePath, content) => {
const response = await fetch(`/api/v1/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();
};