Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 47 additions & 21 deletions frontend/src/pages/BlogAdminPage.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { useDropzone } from 'react-dropzone';
import { useNavigate, useParams } from 'react-router-dom';
import slugify from 'slugify';
import api from '../services/loginService';
import uploadService from '../services/uploadService';



Expand Down Expand Up @@ -152,31 +153,56 @@ const BlogAdminPage = () => {
}
};

// Handle image uploads
const onDrop = useCallback(async (acceptedFiles) => {
// Normally, you'd upload this to your server or a storage service
// For this example, we'll use a placeholder approach
try {
// Simulate uploading to backend/storage
// In a real app, you'd use FormData and send to your backend or S3/etc.
console.log('Uploading files:', acceptedFiles);
// // Handle image uploads
// const onDrop = useCallback(async (acceptedFiles) => {
// // Normally, you'd upload this to your server or a storage service
// // For this example, we'll use a placeholder approach
// try {
// // Simulate uploading to backend/storage
// // In a real app, you'd use FormData and send to your backend or S3/etc.
// console.log('Uploading files:', acceptedFiles);

// Assuming your backend returns a URL to the uploaded image
const imageUrl = URL.createObjectURL(acceptedFiles[0]);
// // Assuming your backend returns a URL to the uploaded image
// const imageUrl = URL.createObjectURL(acceptedFiles[0]);

// Insert the image into the editor
if (editor) {
editor.chain().focus().setImage({ src: imageUrl }).run();
}
// // Insert the image into the editor
// if (editor) {
// editor.chain().focus().setImage({ src: imageUrl }).run();
// }

// For featured image
if (acceptedFiles[0].type.includes('image')) {
setFormData(prev => ({ ...prev, featured_image: imageUrl }));
}
} catch (error) {
console.error('Error uploading file:', error);
// // For featured image
// if (acceptedFiles[0].type.includes('image')) {
// setFormData(prev => ({ ...prev, featured_image: imageUrl }));
// }
// } catch (error) {
// console.error('Error uploading file:', error);
// }
// }, [editor]);

// Handle image uploads
const onDrop = useCallback(async (acceptedFiles) => {
try {
console.log('Uploading files:', acceptedFiles);

const file = acceptedFiles[0];

// Upload to backend which will store in Supabase
const imageUrl = await uploadService.uploadImage(file);

// Insert the image into the editor
if (editor) {
editor.chain().focus().setImage({ src: imageUrl }).run();
}

// For featured image
if (file.type.includes('image')) {
setFormData(prev => ({ ...prev, featured_image: imageUrl }));
}
}, [editor]);
} catch (error) {
console.error('Error uploading file:', error);
// You might want to add error handling here (show toast notification, etc.)
}
}, [editor]);

const { getRootProps, getInputProps } = useDropzone({
onDrop,
Expand Down
101 changes: 101 additions & 0 deletions frontend/src/services/uploadService.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
// // uploadService.js
// import axios from 'axios';
// const API_URL = import.meta.env.VITE_API_URL || 'http://localhost:5000/api';

// // Create an axios instance with default config
// const api = axios.create({
// baseURL: `${API_URL}`,
// headers: {
// 'Content-Type': 'application/json',
// },
// });

// // Helper function to get auth token
// const getAuthToken = () => localStorage.getItem('token');

// // Attach JWT token to request headers if available
// const authHeaders = () => {
// const token = getAuthToken();
// return token ? { Authorization: `Bearer ${token}` } : {};
// };

// // Upload image to the server
// const uploadImage = async (file) => {
// try {
// const formData = new FormData();
// formData.append('image', file);

// const response = await api.post(`${API_URL}/uploads/image`, formData, {
// headers: {
// 'Content-Type': 'multipart/form-data',
// ...authHeaders()
// }
// });
// // debug
// console.log('Image upload response:', response.data);
// // Assuming the response contains the image URL
// return response.data.imageUrl;
// } catch (error) {
// console.error('Error uploading image:', error);
// throw error;
// }
// };

// export default {
// api,
// getAuthToken,
// authHeaders,
// uploadImage
// };

// uploadService.js
import axios from 'axios';
const API_URL = import.meta.env.VITE_API_URL || 'http://localhost:5000/api';

// Create an axios instance with default config
const api = axios.create({
baseURL: API_URL,
headers: {
'Content-Type': 'application/json',
},
});

// Helper function to get auth token
const getAuthToken = () => localStorage.getItem('access_token');

// Attach JWT token to request headers if available
const authHeaders = () => {
const token = getAuthToken();
return token ? { Authorization: `Bearer ${token}` } : {};
};

// Upload image to the server
const uploadImage = async (file) => {
try {
const formData = new FormData();
formData.append('image', file);

// console.log('Token:', localStorage.getItem('access_token'));
// Use the api instance but don't repeat the base URL
// Just use the relative path
const response = await axios.post(`${API_URL}/uploads/image`, formData, {
headers: {
'Content-Type': 'multipart/form-data',
...authHeaders()
}
});

console.log('Image upload response:', response.data);
return response.data.imageUrl;
} catch (error) {
console.error('Error uploading image:', error);
throw error;
}
};

export default {
api,
getAuthToken,
authHeaders,
uploadImage
};
2 changes: 1 addition & 1 deletion server/api/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@
api_bp = Blueprint('api', __name__)

# Import routes to register them with the blueprint
from api import contact_routes, auth_routes, blog_routes
from api import contact_routes, auth_routes, blog_routes, upload_routes
Binary file modified server/api/__pycache__/__init__.cpython-312.pyc
Binary file not shown.
Loading
Loading