Skip to content

Commit

Permalink
Merge pull request #15 from Ecell-NITS/bishal_backend
Browse files Browse the repository at this point in the history
Team Management Backend and Metadata addition
  • Loading branch information
Ruler45 authored Dec 30, 2024
2 parents 11bac20 + 8593068 commit 2884090
Show file tree
Hide file tree
Showing 20 changed files with 449 additions and 59 deletions.
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,14 @@
"next-pwa": "^5.6.0",
"nodemailer": "^6.9.16",
"otplib": "^12.0.1",
"react-icons": "^5.4.0",
"react-icons": "^5.4.0",
"react": "^18",
"react-dom": "^18",
"react-toastify": "^11.0.2",
"sass": "^1.71.1",
"typescript": "^5.6.3",
"uuid": "^11.0.3",
"zod": "^3.24.1"

},
"devDependencies": {
"@types/react": "18.3.2",
Expand Down
30 changes: 21 additions & 9 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Binary file added public/images/placeholder_image.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
11 changes: 11 additions & 0 deletions src/app/(pages)/developers/page.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,17 @@ import Image from "next/image";
import styles from "./developers.module.scss";
import developers from "../../../../public/data/developer.json";

export async function generateMetadata() {
return {
title: "Developers | E-cell, NIT Silchar",
description: "Meet the developers from E-cell, NIT Silchar.",
openGraph: {
title: "Developers | E-cell, NIT Silchar",
description: "Meet the developers from E-cell, NIT Silchar.",
},
};
}

const Developers = () => {
return (
<div className={styles.devContainer}>
Expand Down
File renamed without changes.
17 changes: 17 additions & 0 deletions src/app/(pages)/feedback/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import Feedback from "./Feedback";

// Dynamic Metadata
export async function generateMetadata() {
return {
title: "Feedback | Share Your Experience",
description: "We value your feedback! Share your experience with us.",
openGraph: {
title: "Feedback | Share Your Experience",
description: "We value your feedback! Share your experience with us.",
},
};
}

export default function FeedbackPage() {
return <Feedback />;
}
16 changes: 8 additions & 8 deletions src/app/(pages)/pricing/page.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,14 @@ const Pricing = () => {
return (
<div>
<Pricecard />
<div style={{ textAlign: "center", paddingTop: "50px" }}>
<h1
className="text-[6vw] md:text-[4vw] text-gray-800"
style={{ fontFamily: "Sofia Pro" }}
>
What others are saying about us?
</h1>
</div>
<div style={{ textAlign: "center", paddingTop: "50px" }}>
<h1
className="text-[6vw] md:text-[4vw] text-gray-800"
style={{ fontFamily: "Sofia Pro" }}
>
What others are saying about us?
</h1>
</div>
<Testimonial />
<Modeling />
<FAQ />
Expand Down
4 changes: 2 additions & 2 deletions src/app/(pages)/resetPassword/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import {
} from "../../../schemas/resetPasswordSchema";
import Form from "../../components/Forms/basicForm";

const SignUp = () => {
const ResetPassword = () => {
const [isOtpSent, setIsOtpSent] = useState(false); // State to manage if OTP is sent or not
const [usernameOrEmail, setUsernameOrEmail] = useState(); // State to manage OTP input
const [validationErrors, setValidationErrors] = useState<{
Expand Down Expand Up @@ -264,4 +264,4 @@ const SignUp = () => {
);
};

export default SignUp;
export default ResetPassword;
62 changes: 62 additions & 0 deletions src/app/(pages)/team/TeamMember.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
"use client";

import { useEffect, useState } from "react";
import Image from "next/image";
import styles from "./team.module.scss";
import "../../globals.scss";

const Team = () => {
const [teamMembers, setTeamMembers] = useState([]);
const [error, setError] = useState("");

useEffect(() => {
const fetchTeamMembers = async () => {
try {
const res = await fetch("/api/v1/getAllTeamMembers", {
method: "GET",
headers: {
"Content-Type": "application/json",
},
});
const data = await res.json();

if (!res.ok) {
throw new Error(data.message || "Failed to fetch team members");
}
setTeamMembers(data.teamMembers);
} catch (err) {
console.error(err.message);
setError("Failed to load team members.");
}
};
fetchTeamMembers();
}, []);

if (error) {
return <p>{error}</p>;
}

return (
<div className={styles.teamContainer}>
<h1>Team Members</h1>
<div className={styles.teamGrid}>
{teamMembers.map((member) => {
return (
<div className={styles.teamCard}>
<Image
className={styles.teamImage}
src={member.image || "/images/placeholder_image.jpg"}
alt={member.name}
width={300}
height={300}
></Image>
<h2 className={styles.teamName}>{member.name}</h2>
<p className={styles.teamRole}>{member.designation}</p>
</div>
);
})}
</div>
</div>
);
};
export default Team;
46 changes: 14 additions & 32 deletions src/app/(pages)/team/page.jsx
Original file line number Diff line number Diff line change
@@ -1,34 +1,16 @@
/* eslint-disable @next/next/no-img-element */
import Team from "./TeamMember";

/* eslint-disable import/extensions */
/* eslint-disable no-unused-vars */
import Image from "next/image";
import styles from "./team.module.scss";
import "../../globals.scss";
import teamMembers from "../../../../public/data/team.json";

const Team = () => {
return (
<div className={styles.teamContainer}>
<h1>Team Members</h1>
<div className={styles.teamGrid}>
{teamMembers.map((member) => {
return (
<div className={styles.teamCard}>
<Image
className={styles.teamImage}
src={member.image}
alt={member.name}
width={300}
height={300}
></Image>
<h2 className={styles.teamName}>{member.name}</h2>
<p className={styles.teamRole}>{member.role}</p>
</div>
);
})}
</div>
</div>
);
export const metadata = {
title: "Meet Our Team | Dedicated Professionals",
description:
"Get to know our team of dedicated professionals committed to delivering excellence.",
openGraph: {
title: "Meet Our Team | Dedicated Professionals",
description:
"Get to know our team of dedicated professionals committed to delivering excellence.",
},
};
export default Team;

export default function TeamPage() {
return <Team />;
}
83 changes: 83 additions & 0 deletions src/app/api/v1/addTeamMember/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
import { NextRequest, NextResponse } from "next/server";
import jwt from "jsonwebtoken";
import moment from "moment-timezone";
import TeamMember from "../../../../model/TeamMember";
import dbConnect from "../../../../lib/dbConnect";

export interface ITeamMember extends Document {
name: string;
designation: string;
email: string;
linkedin?: string;
image?: string;
createdAt: Date;
updatedAt: Date;
}

export async function POST(req: NextRequest) {
await dbConnect();

if (req.method !== "POST") {
return NextResponse.json(
{ message: `Method ${req.method} Not Allowed` },
{ status: 405 },
);
}

const token = req.cookies.get("signInToken")?.value || "";

if (!token) {
return NextResponse.json(
{ message: "Unauthorized: No token provided" },
{ status: 401 },
);
}

try {
const decoded = await jwt.verify(token, process.env.JWT_TOKEN_SECRET);

if (decoded.role !== "admin") {
return NextResponse.json(
{ message: "Forbidden: Admin access required" },
{ status: 403 },
);
}

try {
const { name, designation, email, linkedin, image } = await req.json();

if (!name || !designation || !email) {
return NextResponse.json(
{ message: "The fields (name,email,designation) are required" },
{ status: 400 },
);
}

const teamMember: ITeamMember = await TeamMember.create({
name,
image,
designation,
email,
linkedin,
createdAt: moment().tz("Asia/Kolkata").format(),
updatedAt: moment().tz("Asia/Kolkata").format(),
});

return NextResponse.json(
{ message: "Team member added successfully", teamMember },
{ status: 201 },
);
} catch (err) {
console.error(err);
return NextResponse.json(
{ message: "Internal Server Error" },
{ status: 500 },
);
}
} catch (err) {
return NextResponse.json(
{ message: "Invalid Authorization token" },
{ status: 401 },
);
}
}
Loading

0 comments on commit 2884090

Please sign in to comment.