Please change the Backend according to my react frontend page and match the routes according to the react frontend #34
namansh70747
started this conversation in
General
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
-
import React, { useState, useEffect } from 'react';
import { BiPlus, BiStore, BiLineChart, BiEdit, BiTrash, BiFilterAlt } from 'react-icons/bi';
import { FiEye, FiTag, FiArchive, FiBookOpen, FiMonitor, FiCoffee, FiWatch, FiStar, FiSmartphone, FiSearch } from 'react-icons/fi';
import axios from 'axios';
import { toast, ToastContainer } from 'react-toastify';
import 'react-toastify/dist/ReactToastify.css';
// Enhanced categories with more options
const categories = [
{ id: 1, name: 'sell', label: 'Sell', icon: FiTag },
{ id: 2, name: 'exchange', label: 'Exchange', icon: FiArchive },
{ id: 3, name: 'Books', icon: FiBookOpen, type: 'sell' },
{ id: 4, name: 'Electronics', icon: FiMonitor, type: 'sell' },
{ id: 5, name: 'Furniture', icon: FiCoffee, type: 'sell' },
{ id: 6, name: 'Accessories', icon: FiWatch, type: 'sell' },
{ id: 7, name: 'Collectibles', icon: FiStar, type: 'sell' },
{ id: 8, name: 'Gadgets', icon: FiSmartphone, type: 'sell' },
];
const Seller = () => {
const [isAddingItem, setIsAddingItem] = useState(false);
const [selectedCategory, setSelectedCategory] = useState({name: 'sell', label: 'Sell'}); // Set default category
const [myListings, setMyListings] = useState([]);
const [isLoading, setIsLoading] = useState(false);
const [stats, setStats] = useState({
totalItems: 0,
totalViews: 0,
activeListings: 0
});
const [searchTerm, setSearchTerm] = useState('');
const [userInfo, setUserInfo] = useState(null);
const [hostels, setHostels] = useState([]);
const [selectedHostel, setSelectedHostel] = useState(null);
const [newItem, setNewItem] = useState({
title: '',
description: '',
price: '',
image: '',
type: 'sell' // Set default type
});
// Token from localStorage for authorization
const token = localStorage.getItem('token');
// Parse JWT token with error handling
const parseJwt = (token) => {
if (!token) return null;
try {
return JSON.parse(atob(token.split('.')[1]));
} catch (e) {
console.error("Error parsing JWT token:", e);
return null;
}
};
// Setup axios default headers and fetch user info
useEffect(() => {
if (token) {
axios.defaults.headers.common['Authorization'] = token;
}, [token]);
// Fetch hostels when component mounts
useEffect(() => {
const fetchHostels = async () => {
try {
const response = await axios.get('http://localhost:8080/hostels');
if (response.data && Array.isArray(response.data)) {
setHostels(response.data);
if (response.data.length > 0) {
setSelectedHostel(response.data[0]);
}
}
} catch (error) {
console.error("Error fetching hostels:", error);
toast.error("Failed to fetch hostels");
}
};
}, []);
// Fetch items when component mounts, userInfo changes, or selectedHostel changes
useEffect(() => {
if (selectedHostel) {
fetchMyItems();
}
}, [userInfo, selectedHostel]);
const fetchMyItems = async () => {
if (!selectedHostel) return;
};
const handleSubmit = async (e) => {
e.preventDefault();
setIsLoading(true);
};
const handleCategorySelect = (category) => {
setSelectedCategory(category);
setNewItem({
...newItem,
type: category.name
});
setIsAddingItem(true);
};
const handleImageUpload = (e) => {
const file = e.target.files[0];
if (file) {
// In a real app, you'd upload to a server and get a URL
// For this demo, we'll use a data URL
const reader = new FileReader();
reader.onloadend = () => {
setNewItem({ ...newItem, image: reader.result });
};
reader.readAsDataURL(file);
}
};
const formatDate = (dateString) => {
if (!dateString) return "N/A";
try {
const date = new Date(dateString);
return date.toLocaleDateString('en-US', { year: 'numeric', month: 'short', day: 'numeric' });
} catch (error) {
console.error("Error formatting date:", error);
return "Invalid Date";
}
};
const handleDeleteItem = async (itemId) => {
try {
// Attempt to delete the item using an API call
await axios.delete(
http://localhost:8080/items/${itemId});};
const handleHostelChange = (hostelId) => {
const hostel = hostels.find(h => h.ID === parseInt(hostelId));
setSelectedHostel(hostel);
};
// Filter items based on search term
const filteredItems = myListings.filter(item =>
item.Title?.toLowerCase().includes(searchTerm.toLowerCase()) ||
item.Description?.toLowerCase().includes(searchTerm.toLowerCase())
);
return (
);
};
export default Seller;
****THIS IS THE CHANGE REQUIRED IN BACKEND **** PLEASE DO THAT
||||---------Below is the idea by Claude ai
After analyzing your code, I'll guide you through the necessary backend changes to match the frontend requirements. The main task is to ensure the backend supports all the functionality demonstrated in the frontend React component, particularly the Seller Dashboard.
Here are the changes needed in your backend (Go) code:
Adding Item Views Support
Line 28-29: Add a Views field to the Item struct:
goCopytype Item struct {
ID uint
gorm:"primaryKey"UserID uint
gorm:"not null"User User
gorm:"foreignKey:UserID"HostelID uint
gorm:"not null"Hostel Hostel
gorm:"foreignKey:HostelID"Title string
gorm:"not null"Description string
gorm:"not null"Price float64
Image string
Status string
gorm:"default:'pending'"Type string
gorm:"not null"Views int
gorm:"default:0"// Add this lineCreatedAt time.Time
UpdatedAt time.Time
}
Implement Item Deletion
Around line 345 (after the getItem function): Add a new handler for deleting items:
goCopyfunc deleteItem(c *gin.Context) {
user := c.MustGet("user").(User)
var item Item
if err := db.First(&item, c.Param("id")).Error; err != nil {
c.JSON(http.StatusNotFound, gin.H{"error": "Item not found"})
return
}
// Check if the user is the owner of the item
if item.UserID != user.ID {
c.JSON(http.StatusForbidden, gin.H{"error": "Not authorized to delete this item"})
return
}
if err := db.Delete(&item).Error; err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to delete item"})
return
}
c.JSON(http.StatusOK, gin.H{"message": "Item deleted successfully"})
}
Update Router to Include New Endpoints
Line 139-140: Add the delete route in the authenticated routes group:
goCopyauth.GET("/items/:id", getItem)
auth.DELETE("/items/:id", deleteItem) // Add this line
auth.POST("/requests", createRequest)
Modify the listItemsByHostel Function
Around line 283: Update to include all items (not just approved ones) and to preload the User relationship:
goCopyfunc listItemsByHostel(c *gin.Context) {
var items []Item
db.Preload("User").Where("hostel_id = ?", c.Param("id")).Find(&items)
c.JSON(http.StatusOK, items)
}
Implement View Counting
Around line 345 (after the getItem function): Update the getItem function to increment views:
goCopyfunc getItem(c *gin.Context) {
var item Item
if err := db.First(&item, c.Param("id")).Error; err != nil {
c.JSON(http.StatusNotFound, gin.H{"error": "Item not found"})
return
}
// Increment views
item.Views++
db.Save(&item)
c.JSON(http.StatusOK, item)
}
Fix the JWT Token Verification
Line 104-121: Update the AuthMiddleware to properly handle the token format from the frontend:
goCopyfunc AuthMiddleware() gin.HandlerFunc {
return func(c *gin.Context) {
tokenString := c.GetHeader("Authorization")
if tokenString == "" {
c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{"error": "Authorization header required"})
return
}
}
}
Ensure the CreateItem Function Works with the Frontend
Line 294-316: Update the createItem function to handle the frontend's request format:
goCopyfunc createItem(c *gin.Context) {
user := c.MustGet("user").(User)
type ItemRequest struct {
Title string
json:"title" binding:"required"Description string
json:"description" binding:"required"Price float64
json:"price"Image string
json:"image"Type string
json:"type" binding:"required"}
var req ItemRequest
if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
// Set a default type if not provided
if req.Type == "" {
req.Type = "sell"
}
item := Item{
UserID: user.ID,
HostelID: user.HostelID,
Title: req.Title,
Description: req.Description,
Price: req.Price,
Image: req.Image,
Type: req.Type,
Status: "approved", // Auto-approve for now to match frontend behavior
}
db.Create(&item)
c.JSON(http.StatusCreated, item)
}
Add an Endpoint for User Profile
Around line 345 (after the getItem function): Add a new handler to get the current user's profile:
goCopyfunc getUserProfile(c *gin.Context) {
user := c.MustGet("user").(User)
c.JSON(http.StatusOK, gin.H{
"id": user.ID,
"name": user.Name,
"email": user.Email,
"hostel_id": user.HostelID,
"role": user.Role,
})
}
Line 139-140: Add the route in the authenticated routes group:
goCopyauth.GET("/profile", getUserProfile) // Add this line
auth.GET("/hostels", listHostels)
Add a JWT Environment Variable
Make sure to add a JWT_SECRET to your .env file:
CopyJWT_SECRET=your_secret_key_here
Update Schema to Support Image Storage
Line 28-29: Modify the Item struct's Image field to handle large text:
goCopyImage string
gorm:"type:text"// Update this lineSummary of Changes:
Added Views field to Item struct
Implemented item deletion functionality
Updated routes to include new endpoints
Modified listItemsByHostel to show all items
Implemented view counting in getItem
Fixed JWT token verification to handle "Bearer " prefix
Updated createItem to better match frontend expectations
Added a user profile endpoint
Added JWT_SECRET configuration
Updated Image field to handle large text data
These changes should make your backend compatible with the frontend React component. You may need to make additional adjustments based on specific interactions between the frontend and backend.
Beta Was this translation helpful? Give feedback.
All reactions