From 6a1c2b441cf1686083677b31db633cf19e9a9eb5 Mon Sep 17 00:00:00 2001 From: Sawan Date: Sun, 10 Nov 2024 14:26:38 +0530 Subject: [PATCH] Added backend frontend for story page --- public/index.html | 2 +- server/app.js | 2 + server/controllers/postsController.js | 25 ++++ server/model/postModel.js | 13 ++ server/routes/storiesRoutes.js | 9 ++ src/App.tsx | 16 ++- src/components/Header.tsx | 10 ++ src/components/Stories.tsx | 182 ++++++++++++++++++++++++++ 8 files changed, 251 insertions(+), 8 deletions(-) create mode 100644 server/controllers/postsController.js create mode 100644 server/model/postModel.js create mode 100644 server/routes/storiesRoutes.js create mode 100644 src/components/Stories.tsx diff --git a/public/index.html b/public/index.html index 8ad9c7d..9f9adea 100644 --- a/public/index.html +++ b/public/index.html @@ -36,7 +36,7 @@ GlassyUI - + diff --git a/server/app.js b/server/app.js index 9b2ee27..55471b9 100644 --- a/server/app.js +++ b/server/app.js @@ -3,6 +3,7 @@ import dotenv from 'dotenv'; import connectDB from './utils/db.js'; import cors from 'cors'; import contactRoutes from './routes/contactRoutes.js'; +import stories from './routes/storiesRoutes.js'; dotenv.config(); const app = express(); @@ -15,6 +16,7 @@ app.use(cors()); // Serve static files from the uploads directory app.use('/api/contact', contactRoutes); +app.use('/api/stories', stories); const PORT = process.env.PORT || 5000; app.listen(PORT, () => { diff --git a/server/controllers/postsController.js b/server/controllers/postsController.js new file mode 100644 index 0000000..5f2a75f --- /dev/null +++ b/server/controllers/postsController.js @@ -0,0 +1,25 @@ +// postsController.js +import Post from '../model/postModel.js'; + +// Fetch all posts +export const getPosts = async (req, res) => { + try { + const posts = await Post.find(); + res.status(200).json(posts); + } catch (error) { + res.status(500).json({ message: 'Error fetching posts', error }); + } +}; + +// Save a new post +export const savePost = async (req, res) => { + const { title, content, category, date } = req.body; + + try { + const newPost = new Post({ title, content, category, date }); + const savedPost = await newPost.save(); + res.status(201).json(savedPost); + } catch (error) { + res.status(500).json({ message: 'Error saving post', error }); + } +}; diff --git a/server/model/postModel.js b/server/model/postModel.js new file mode 100644 index 0000000..b8dbc18 --- /dev/null +++ b/server/model/postModel.js @@ -0,0 +1,13 @@ +// postModel.js +import mongoose from 'mongoose'; + +const postSchema = new mongoose.Schema({ + title: String, + content: String, + category: String, + date: { type: Date, default: Date.now }, +}); + +const Post = mongoose.model('Post', postSchema); + +export default Post; diff --git a/server/routes/storiesRoutes.js b/server/routes/storiesRoutes.js new file mode 100644 index 0000000..44a77d8 --- /dev/null +++ b/server/routes/storiesRoutes.js @@ -0,0 +1,9 @@ +import express from 'express'; +import { getPosts, savePost } from '../controllers/postsController.js'; + +const router = express.Router(); + +router.get('/getposts', getPosts); +router.post('/saveposts', savePost); + +export default router; diff --git a/src/App.tsx b/src/App.tsx index 8d9c299..fed3747 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -43,10 +43,11 @@ import Statistic from './components/StatisticDetails'; import GalleryDetailsPage from './components/GalleryDetailsPage'; import SpinnerDetailsPage from './components/SpinnerDetailsPage'; import ProductCardDetailsPage from './components/ProductCardDetailsPage'; - import ContactUs from './components/ContactUs'; - import AiChatbot from './components/AIChatbot'; - import { TermsOfUse } from './components/TermsOfUse'; - +import ContactUs from './components/ContactUs'; +import AiChatbot from './components/AIChatbot'; +import { TermsOfUse } from './components/TermsOfUse'; +import Stories from './components/Stories'; + const ThemeToggle: React.FC = () => { const [theme, setTheme] = useState(localStorage.getItem('theme') || 'light'); @@ -116,9 +117,10 @@ const App: React.FC = () => { } /> } /> } /> - } /> - } /> - } /> + } /> + } /> + } /> + } /> diff --git a/src/components/Header.tsx b/src/components/Header.tsx index 6585ebe..4e78c23 100644 --- a/src/components/Header.tsx +++ b/src/components/Header.tsx @@ -73,6 +73,16 @@ const Header: React.FC = () => { Contact Us +
  • + (e.currentTarget.style.color = '#fde047')} + onMouseLeave={e => (e.currentTarget.style.color = 'white')} + > + Stories + +
    • { + const [posts, setPosts] = useState([]); + const [title, setTitle] = useState(''); + const [content, setContent] = useState(''); + const [category, setCategory] = useState(''); + + useEffect(() => { + // Fetch posts from the backend API + const fetchPosts = async () => { + try { + const response = await fetch( + 'http://localhost:5000/api/stories/getposts', + ); + if (response.ok) { + const data = await response.json(); + setPosts(data); + } else { + console.error('Failed to fetch posts'); + } + } catch (error) { + console.error('Error fetching posts:', error); + } + }; + + fetchPosts(); + }, []); + + const handleSubmit = async (e: React.FormEvent) => { + e.preventDefault(); + + if (title && content && category) { + const newPost = { + title, + content, + category, + date: new Date().toISOString(), + }; + + try { + const response = await fetch( + 'http://localhost:5000/api/stories/saveposts', + { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify(newPost), + }, + ); + + if (response.ok) { + const savedPost = await response.json(); + setPosts([savedPost, ...posts]); // Add the new post to state + } else { + console.error('Failed to save the post'); + } + } catch (error) { + console.error('Error saving the post:', error); + } + + // Clear form fields + setTitle(''); + setContent(''); + setCategory(''); + } + }; + + return ( + <> +

      + Real Stories, Real Advice: Share Your Experience +

      + +
      + {/* Left side - Posts */} +
      + {posts.length === 0 ? ( +

      + No posts yet. Share your experience! +

      + ) : ( + posts.map((post, index) => ( +
      +

      + {post.title} +

      +

      + {post.category} +

      +

      + {post.content} +

      +
      +

      + {new Date(post.date).toLocaleDateString()} +

      + +
      +
      + )) + )} +
      + + {/* Right side - Form */} +
      +
      + setTitle(e.target.value)} + className='w-full p-3 rounded-md border border-gray-600 bg-gray-700 text-white focus:outline-none focus:border-blue-500' + /> + + + + +
      +
      +
      + + ); +}; + +export default Stories;