Skip to content
Open
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
13 changes: 13 additions & 0 deletions backend/models/feedback.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import mongoose from "mongoose";

const feedbackSchema = new mongoose.Schema({
userId: { type: String, default: null }, // null if anonymous
rating: { type: Number, required: true, min: 1, max: 5 },
comment: { type: String, required: true },
category: { type: String, default: "General" },
date: { type: Date, default: Date.now },
});

const Feedback = mongoose.model("Feedback", feedbackSchema);

export default Feedback;
30 changes: 30 additions & 0 deletions backend/routes/feedback.route.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import express from "express";
import Feedback from "../models/feedback.js";

const router = express.Router();

// POST /api/feedback
router.post("/", async (req, res) => {
try {
const { userId, rating, comment, category } = req.body;

if (!rating || !comment) {
return res.status(400).json({ error: "Rating and comment required" });
}

const feedback = await Feedback.create({
userId,
rating,
comment,
category,
date: new Date()
});

res.status(201).json({ message: "Feedback saved", feedback });
} catch (err) {
console.error("Feedback error:", err);
res.status(500).json({ error: "Server error" });
}
});

export default router;
98 changes: 51 additions & 47 deletions backend/server.js
Original file line number Diff line number Diff line change
@@ -1,66 +1,70 @@
// Entry point of the backend server
require("dotenv").config();
const dbconnection = require("./db/connection");
const express = require("express");
const mongoose = require("mongoose");
const cors = require("cors");
const path = require("path");
const contactRouter = require("./routes/contact.route");
const passport = require("passport"); // import actual passport
require("./config/passport"); // just execute the strategy config
const session = require("express-session");


// Importing Rate Limiter Middlewares

const { generalMiddleware, authMiddleware } = require("./middleware/rateLimit/index")



// Initialize express
// backend/server.js
import express from "express";
import mongoose from "mongoose";
import cors from "cors";
import dotenv from "dotenv";
import path from "path";
import session from "express-session";
import passport from "passport";
import { fileURLToPath } from "url";

import feedbackRoutes from "./routes/feedback.route.js";
import contactRouter from "./routes/contact.route.js";
import profileRoutes from "./routes/profile.js";
// import authRoutes from "./routes/auth.js"; // enable when ready

import { generalMiddleware, authMiddleware } from "./middleware/rateLimit/index.js";
import "./config/passport.js"; // configure passport strategies

dotenv.config();
const app = express();

// Middleware
app.use(express.json());
app.use(cors({
origin: process.env.CLIENT_URL || "http://localhost:5173", // frontend URL for local dev
credentials: true
}));


app.use(
cors({
origin: process.env.CLIENT_URL || "http://localhost:5173", // frontend URL
credentials: true,
})
);

app.use(
session({
secret: process.env.SESSION_SECRET || "devsync_session_secret",
resave: false,
saveUninitialized: false,
cookie: { secure: false } // set true if using HTTPS
})
session({
secret: process.env.SESSION_SECRET || "devsync_session_secret",
resave: false,
saveUninitialized: false,
cookie: { secure: false }, // set true if using HTTPS
})
);

app.use(passport.initialize());
app.use(passport.session());

// Serve uploaded files
app.use("/uploads", express.static(path.join(__dirname, "uploads")));

// Define routes

// app.use("/api/auth", require("./routes/auth"));
app.use("/api/auth", authMiddleware, require("./routes/auth"));
// Fix __dirname in ES modules
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

// app.use("/api/profile", require("./routes/profile"));
app.use("/api/profile", generalMiddleware, require("./routes/profile"));
// Serve static uploads
app.use("/uploads", express.static(path.join(__dirname, "uploads")));

// app.use("/api/contact",contactRouter);
// Routes
app.use("/api/feedback", feedbackRoutes);
// app.use("/api/auth", authMiddleware, authRoutes); // enable when ready
app.use("/api/profile", generalMiddleware, profileRoutes);
app.use("/api/contact", generalMiddleware, contactRouter);


// Route to display the initial message on browser
// Root route
app.get("/", (req, res) => {
res.send("DEVSYNC BACKEND API");
res.send("DEVSYNC BACKEND API");
});

// Connect DB and start server
mongoose
.connect(process.env.MONGO_URI)
.then(() => console.log("βœ… MongoDB connected"))
.catch((err) => console.error("❌ DB error:", err));

const PORT = process.env.PORT || 5000;
app.listen(PORT, () => {
console.log(`Server is up and running at http://localhost:${PORT} πŸš€`);
});
console.log(`πŸš€ Server running at http://localhost:${PORT}`);
});
13 changes: 6 additions & 7 deletions frontend/src/Components/Navbar/Navbar.jsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import React, { useEffect, useState } from "react";
import { Github, Home, Info, Sparkle, LogIn, UserPlus, UserCircle } from "lucide-react";
import { Github, Home, Info, Sparkle, LogIn, UserPlus, UserCircle, Phone } from "lucide-react";
import { FloatingNav } from "../ui/floating-navbar";
import { Phone } from "lucide-react";
import { Link } from "react-router-dom";
import FeedbackModal from "../ui/FeedbackModal";

const navItems = [
{
Expand Down Expand Up @@ -44,21 +44,20 @@ const Navbar = () => {
return () => window.removeEventListener("scroll", handleScroll);
}, []);

const isAuthenticated = localStorage.getItem('token') !== null;
const isAuthenticated = localStorage.getItem("token") !== null;
const userId = localStorage.getItem("userId");

return (
<div className="w-full font-sans">
{!showFloating && (
<header className="fixed top-0 left-0 right-0 z-50 bg-gradient-to-b from-[#E4ECF1]/80 to-[#D2DEE7]/80 backdrop-blur-xl border-b border-[#C5D7E5] px-6 py-4 shadow-md">
<div className="mx-auto flex max-w-7xl items-center justify-between">
{/* Logo */}
<Link to="/">
<h1 className="text-4xl font-extrabold text-transparent bg-clip-text bg-gradient-to-r from-[#2E3A59] to-[#2E3A59]">
DevSync
</h1>
</Link>

{/* Desktop Navigation */}
<nav className="hidden md:flex space-x-8 items-center">
{navItems.map((item) => (
<a
Expand Down Expand Up @@ -100,7 +99,6 @@ const Navbar = () => {
</div>
</nav>

{/* Mobile Menu Button */}
<div className="md:hidden">
<button
onClick={() => setMenuOpen(!menuOpen)}
Expand All @@ -111,7 +109,6 @@ const Navbar = () => {
</div>
</div>

{/* Mobile Navigation */}
{menuOpen && (
<div className="md:hidden mt-4 flex flex-col gap-3 px-4 pb-4">
{navItems.map((item) => (
Expand Down Expand Up @@ -158,6 +155,8 @@ const Navbar = () => {
)}

{showFloating && <FloatingNav navItems={navItems} />}

<FeedbackModal userId={userId} justLoggedIn={isAuthenticated} />
</div>
);
};
Expand Down
Loading