├── jsconfig.json
├── next.config.js
├── postcss.config.js
├── src
├── app
│ ├── favicon.ico
│ ├── layout.js
│ ├── api
│ │ ├── home
│ │ │ ├── get
│ │ │ │ └── route.js
│ │ │ ├── add
│ │ │ │ └── route.js
│ │ │ └── update
│ │ │ │ └── route.js
│ │ ├── about
│ │ │ ├── get
│ │ │ │ └── route.js
│ │ │ ├── add
│ │ │ │ └── route.js
│ │ │ └── update
│ │ │ │ └── route.js
│ │ ├── contact
│ │ │ ├── get
│ │ │ │ └── route.js
│ │ │ └── add
│ │ │ │ └── route.js
│ │ ├── project
│ │ │ ├── get
│ │ │ │ └── route.js
│ │ │ └── add
│ │ │ │ └── route.js
│ │ ├── education
│ │ │ ├── get
│ │ │ │ └── route.js
│ │ │ └── add
│ │ │ │ └── route.js
│ │ ├── experience
│ │ │ ├── get
│ │ │ │ └── route.js
│ │ │ └── add
│ │ │ │ └── route.js
│ │ └── login
│ │ │ └── route.js
│ ├── page.js
│ ├── globals.css
│ └── admin
│ │ └── page.js
├── assets
│ ├── ai-image.png
│ └── about-image.png
├── models
│ ├── Home.js
│ ├── User.js
│ ├── Contact.js
│ ├── Education.js
│ ├── Project.js
│ ├── About.js
│ └── Experience.js
├── database
│ └── index.js
├── components
│ ├── client-view
│ │ ├── common-layout
│ │ │ └── index.js
│ │ ├── animation-wrapper
│ │ │ └── index.js
│ │ ├── navbar
│ │ │ └── index.js
│ │ ├── project
│ │ │ └── index.js
│ │ ├── home
│ │ │ └── index.js
│ │ ├── about
│ │ │ └── index.js
│ │ ├── contact
│ │ │ └── index.js
│ │ └── experience
│ │ │ └── index.js
│ └── admin-view
│ │ ├── contact
│ │ └── index.js
│ │ ├── form-controls
│ │ └── index.js
│ │ ├── login
│ │ └── index.js
│ │ ├── home
│ │ └── index.js
│ │ ├── about
│ │ └── index.js
│ │ ├── education
│ │ └── index.js
│ │ ├── project
│ │ └── index.js
│ │ └── experience
│ │ └── index.js
└── services
│ └── index.js
├── .gitignore
├── public
├── vercel.svg
└── next.svg
├── package.json
├── README.md
└── tailwind.config.js
/jsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "paths": {
4 | "@/*": ["./src/*"]
5 | }
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/next.config.js:
--------------------------------------------------------------------------------
1 | /** @type {import('next').NextConfig} */
2 | const nextConfig = {}
3 |
4 | module.exports = nextConfig
5 |
--------------------------------------------------------------------------------
/postcss.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | plugins: {
3 | tailwindcss: {},
4 | autoprefixer: {},
5 | },
6 | }
7 |
--------------------------------------------------------------------------------
/src/app/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sangammukherjee/NextJS-Fullstack-Portfolio-2023/HEAD/src/app/favicon.ico
--------------------------------------------------------------------------------
/src/assets/ai-image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sangammukherjee/NextJS-Fullstack-Portfolio-2023/HEAD/src/assets/ai-image.png
--------------------------------------------------------------------------------
/src/assets/about-image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sangammukherjee/NextJS-Fullstack-Portfolio-2023/HEAD/src/assets/about-image.png
--------------------------------------------------------------------------------
/src/models/Home.js:
--------------------------------------------------------------------------------
1 | import mongoose from "mongoose";
2 |
3 | const HomeSchema = new mongoose.Schema(
4 | {
5 | heading: String,
6 | summary: String,
7 | },
8 | { timestamps: true }
9 | );
10 |
11 | const Home = mongoose.models.Home || mongoose.model("Home", HomeSchema);
12 |
13 | export default Home;
14 |
--------------------------------------------------------------------------------
/src/models/User.js:
--------------------------------------------------------------------------------
1 | import mongoose from "mongoose";
2 |
3 | const UserSchema = new mongoose.Schema(
4 | {
5 | username: String,
6 | password: String,
7 | },
8 | { timestamps: true }
9 | );
10 |
11 | const User = mongoose.models.User || mongoose.model("User", UserSchema);
12 |
13 | export default User;
14 |
--------------------------------------------------------------------------------
/src/models/Contact.js:
--------------------------------------------------------------------------------
1 | import mongoose from "mongoose";
2 |
3 | const ContactSchema = new mongoose.Schema({
4 | name : String,
5 | email : String,
6 | message : String
7 | }, {timestamps : true})
8 |
9 | const Contact = mongoose.models.Contacts || mongoose.model('Contacts', ContactSchema)
10 |
11 | export default Contact;
--------------------------------------------------------------------------------
/src/database/index.js:
--------------------------------------------------------------------------------
1 | import mongoose from "mongoose";
2 |
3 | export default async function connectToDB() {
4 | try {
5 | await mongoose.connect(
6 | "mongodb+srv://sangam:sangam2023@cluster0.7aauitj.mongodb.net/"
7 | );
8 | console.log("Database connected successfully");
9 | } catch (e) {
10 | console.log(e);
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/src/models/Education.js:
--------------------------------------------------------------------------------
1 | import mongoose from "mongoose";
2 |
3 | const EducationSchema = new mongoose.Schema(
4 | {
5 | degree: String,
6 | year: String,
7 | college: String,
8 | },
9 | { timestamps: true }
10 | );
11 |
12 | const Education = mongoose.models.Education || mongoose.model("Education", EducationSchema);
13 |
14 | export default Education;
--------------------------------------------------------------------------------
/src/components/client-view/common-layout/index.js:
--------------------------------------------------------------------------------
1 | "use client";
2 | import { usePathname } from "next/navigation";
3 | import Navbar from "../navbar";
4 |
5 | export default function CommonLayout({ children }) {
6 | const pathName = usePathname();
7 | return (
8 | <>
9 | {pathName !== "/admin" ? : null}
10 | {children}
11 | >
12 | );
13 | }
14 |
--------------------------------------------------------------------------------
/src/models/Project.js:
--------------------------------------------------------------------------------
1 | import mongoose from "mongoose";
2 |
3 | const ProjectSchema = new mongoose.Schema(
4 | {
5 | name: String,
6 | website: String,
7 | technologies: String,
8 | github: String,
9 | },
10 | { timestamps: true }
11 | );
12 |
13 | const Project =
14 | mongoose.models.Project || mongoose.model("Project", ProjectSchema);
15 |
16 | export default Project;
17 |
--------------------------------------------------------------------------------
/src/models/About.js:
--------------------------------------------------------------------------------
1 | import mongoose from "mongoose";
2 |
3 | const AboutSchema = new mongoose.Schema(
4 | {
5 | aboutme: String,
6 | noofprojects: String,
7 | yearofexperience: String,
8 | noofclients: String,
9 | skills: String,
10 | },
11 | { timestamps: true }
12 | );
13 |
14 | const About = mongoose.models.About || mongoose.model("About", AboutSchema);
15 |
16 | export default About;
--------------------------------------------------------------------------------
/src/models/Experience.js:
--------------------------------------------------------------------------------
1 | import mongoose from "mongoose";
2 |
3 | const ExperienceSchema = new mongoose.Schema(
4 | {
5 | position: String,
6 | company: String,
7 | duration: String,
8 | location: String,
9 | jobprofile: String,
10 | },
11 | { timestamps: true }
12 | );
13 |
14 | const Experience = mongoose.models.Experience || mongoose.model("Experience", ExperienceSchema);
15 |
16 | export default Experience;
--------------------------------------------------------------------------------
/src/components/client-view/animation-wrapper/index.js:
--------------------------------------------------------------------------------
1 | "use client";
2 | import { motion } from "framer-motion";
3 |
4 | export default function AnimationWrapper({ children, className, ...props }) {
5 | return (
6 |
13 | {children}
14 |
15 | );
16 | }
17 |
--------------------------------------------------------------------------------
/src/components/admin-view/contact/index.js:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | export default function AdminContactView({ data }) {
4 | return (
5 |
6 | {data && data.length
7 | ? data.map((item) => (
8 |
9 |
{item.name}
10 |
{item.email}
11 |
{item.message}
12 |
13 | ))
14 | : null}
15 |
16 | );
17 | }
18 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 |
8 | # testing
9 | /coverage
10 |
11 | # next.js
12 | /.next/
13 | /out/
14 |
15 | # production
16 | /build
17 |
18 | # misc
19 | .DS_Store
20 | *.pem
21 |
22 | # debug
23 | npm-debug.log*
24 | yarn-debug.log*
25 | yarn-error.log*
26 |
27 | # local env files
28 | .env*.local
29 |
30 | # vercel
31 | .vercel
32 |
33 | # typescript
34 | *.tsbuildinfo
35 | next-env.d.ts
36 |
--------------------------------------------------------------------------------
/src/app/layout.js:
--------------------------------------------------------------------------------
1 | import CommonLayout from '@/components/client-view/common-layout'
2 | import './globals.css'
3 | import { Inter } from 'next/font/google'
4 |
5 | const inter = Inter({ subsets: ['latin'] })
6 |
7 | export const metadata = {
8 | title: 'Create Next App',
9 | description: 'Generated by create next app',
10 | }
11 |
12 | export default function RootLayout({ children }) {
13 | return (
14 |
15 |
16 | {children}
17 |
18 |
19 | )
20 | }
21 |
--------------------------------------------------------------------------------
/public/vercel.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/app/api/home/get/route.js:
--------------------------------------------------------------------------------
1 | import connectToDB from "@/database";
2 | import Home from "@/models/Home";
3 | import { NextResponse } from "next/server";
4 |
5 | export const dynamic = "force-dynamic";
6 |
7 | export async function GET(req) {
8 | try {
9 | await connectToDB();
10 | const extractData = await Home.find({});
11 |
12 | if (extractData) {
13 | return NextResponse.json({
14 | success: true,
15 | data: extractData,
16 | });
17 | } else {
18 | return NextResponse.json({
19 | success: false,
20 | message: "Something went wrong !Please try again",
21 | });
22 | }
23 | } catch (e) {
24 | console.log(e);
25 |
26 | return NextResponse.json({
27 | success: false,
28 | message: "Something went wrong !Please try again",
29 | });
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/src/app/api/about/get/route.js:
--------------------------------------------------------------------------------
1 | import connectToDB from "@/database";
2 | import About from "@/models/About";
3 | import { NextResponse } from "next/server";
4 |
5 | export const dynamic = "force-dynamic";
6 |
7 | export async function GET(req) {
8 | try {
9 | await connectToDB();
10 | const extractData = await About.find({});
11 |
12 | if (extractData) {
13 | return NextResponse.json({
14 | success: true,
15 | data: extractData,
16 | });
17 | } else {
18 | return NextResponse.json({
19 | success: false,
20 | message: "Something went wrong !Please try again",
21 | });
22 | }
23 | } catch (e) {
24 | console.log(e);
25 |
26 | return NextResponse.json({
27 | success: false,
28 | message: "Something went wrong !Please try again",
29 | });
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/src/app/api/contact/get/route.js:
--------------------------------------------------------------------------------
1 | import connectToDB from "@/database";
2 | import Contact from "@/models/Contact";
3 | import { NextResponse } from "next/server";
4 |
5 | export const dynamic = "force-dynamic";
6 |
7 | export async function GET(req) {
8 | try {
9 | await connectToDB();
10 | const extractData = await Contact.find({});
11 |
12 | if (extractData) {
13 | return NextResponse.json({
14 | success: true,
15 | data: extractData,
16 | });
17 | } else {
18 | return NextResponse.json({
19 | success: false,
20 | message: "Something went wrong !Please try again",
21 | });
22 | }
23 | } catch (e) {
24 | console.log(e);
25 |
26 | return NextResponse.json({
27 | success: false,
28 | message: "Something went wrong !Please try again",
29 | });
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/src/app/api/project/get/route.js:
--------------------------------------------------------------------------------
1 | import connectToDB from "@/database";
2 | import Project from "@/models/Project";
3 | import { NextResponse } from "next/server";
4 |
5 | export const dynamic = "force-dynamic";
6 |
7 | export async function GET(req) {
8 | try {
9 | await connectToDB();
10 | const extractData = await Project.find({});
11 |
12 | if (extractData) {
13 | return NextResponse.json({
14 | success: true,
15 | data: extractData,
16 | });
17 | } else {
18 | return NextResponse.json({
19 | success: false,
20 | message: "Something went wrong !Please try again",
21 | });
22 | }
23 | } catch (e) {
24 | console.log(e);
25 |
26 | return NextResponse.json({
27 | success: false,
28 | message: "Something went wrong !Please try again",
29 | });
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/src/app/api/education/get/route.js:
--------------------------------------------------------------------------------
1 | import connectToDB from "@/database";
2 | import Education from "@/models/Education";
3 | import { NextResponse } from "next/server";
4 |
5 | export const dynamic = "force-dynamic";
6 |
7 | export async function GET(req) {
8 | try {
9 | await connectToDB();
10 | const extractData = await Education.find({});
11 |
12 | if (extractData) {
13 | return NextResponse.json({
14 | success: true,
15 | data: extractData,
16 | });
17 | } else {
18 | return NextResponse.json({
19 | success: false,
20 | message: "Something went wrong !Please try again",
21 | });
22 | }
23 | } catch (e) {
24 | console.log(e);
25 |
26 | return NextResponse.json({
27 | success: false,
28 | message: "Something went wrong !Please try again",
29 | });
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "nextjs-portfolio-2023",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "dev": "next dev",
7 | "build": "next build",
8 | "start": "next start",
9 | "lint": "next lint"
10 | },
11 | "dependencies": {
12 | "@emotion/react": "^11.11.1",
13 | "@emotion/styled": "^11.11.0",
14 | "@fullhuman/postcss-purgecss": "^5.0.0",
15 | "@mui/lab": "^5.0.0-alpha.142",
16 | "@mui/material": "^5.14.7",
17 | "autoprefixer": "10.4.15",
18 | "bcryptjs": "^2.4.3",
19 | "framer-motion": "^10.16.2",
20 | "mongoose": "^7.5.0",
21 | "next": "13.4.19",
22 | "postcss": "8.4.29",
23 | "react": "18.2.0",
24 | "react-dom": "18.2.0",
25 | "react-icons": "^4.10.1",
26 | "react-scroll": "^1.8.9",
27 | "react-slick": "^0.29.0",
28 | "tailwindcss": "3.3.3"
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/src/app/api/experience/get/route.js:
--------------------------------------------------------------------------------
1 | import connectToDB from "@/database";
2 | import Experience from "@/models/Experience";
3 | import { NextResponse } from "next/server";
4 |
5 | export const dynamic = "force-dynamic";
6 |
7 | export async function GET(req) {
8 | try {
9 | await connectToDB();
10 | const extractData = await Experience.find({});
11 |
12 | if (extractData) {
13 | return NextResponse.json({
14 | success: true,
15 | data: extractData,
16 | });
17 | } else {
18 | return NextResponse.json({
19 | success: false,
20 | message: "Something went wrong !Please try again",
21 | });
22 | }
23 | } catch (e) {
24 | console.log(e);
25 |
26 | return NextResponse.json({
27 | success: false,
28 | message: "Something went wrong !Please try again",
29 | });
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/src/app/api/home/add/route.js:
--------------------------------------------------------------------------------
1 | import connectToDB from "@/database";
2 | import Home from "@/models/Home";
3 | import { NextResponse } from "next/server";
4 |
5 | export const dynamic = "force-dynamic";
6 |
7 | export async function POST(req) {
8 | try {
9 | await connectToDB();
10 | const extractData = await req.json();
11 | const saveData = await Home.create(extractData);
12 |
13 | if (saveData) {
14 | return NextResponse.json({
15 | success: true,
16 | message: "Data saved successfully",
17 | });
18 | } else {
19 | return NextResponse.json({
20 | success: false,
21 | message: "Something goes wrong !Please try again",
22 | });
23 | }
24 | } catch (e) {
25 | console.log(e);
26 |
27 | return NextResponse.json({
28 | success: false,
29 | message: "Something goes wrong !Please try again",
30 | });
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/src/components/admin-view/form-controls/index.js:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | export default function FormControls({ controls, formData, setFormData }) {
4 | return controls.map((controlItem) => (
5 |
6 |
9 | {
16 | setFormData({
17 | ...formData,
18 | [controlItem.name]: e.target.value,
19 | });
20 | }}
21 | className="shadow border rounded w-full py-2 px-3 text-gray-700 tracking-wide focus:outline-none focus:shadow-outline"
22 | />
23 |
24 | ));
25 | }
26 |
--------------------------------------------------------------------------------
/src/app/api/about/add/route.js:
--------------------------------------------------------------------------------
1 | import connectToDB from "@/database";
2 | import About from "@/models/About";
3 | import { NextResponse } from "next/server";
4 |
5 | export const dynamic = "force-dynamic";
6 |
7 | export async function POST(req) {
8 | try {
9 | await connectToDB();
10 | const extractData = await req.json();
11 | const saveData = await About.create(extractData);
12 |
13 | if (saveData) {
14 | return NextResponse.json({
15 | success: true,
16 | message: "Data saved successfully",
17 | });
18 | } else {
19 | return NextResponse.json({
20 | success: false,
21 | message: "Something goes wrong !Please try again",
22 | });
23 | }
24 | } catch (e) {
25 | console.log(e);
26 |
27 | return NextResponse.json({
28 | success: false,
29 | message: "Something goes wrong !Please try again",
30 | });
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/src/app/api/contact/add/route.js:
--------------------------------------------------------------------------------
1 | import connectToDB from "@/database";
2 | import Contact from "@/models/Contact";
3 | import { NextResponse } from "next/server";
4 |
5 | export const dynamic = "force-dynamic";
6 |
7 | export async function POST(req) {
8 | try {
9 | await connectToDB();
10 | const extractData = await req.json();
11 | const saveData = await Contact.create(extractData);
12 |
13 | if (saveData) {
14 | return NextResponse.json({
15 | success: true,
16 | message: "Data saved successfully",
17 | });
18 | } else {
19 | return NextResponse.json({
20 | success: false,
21 | message: "Something goes wrong !Please try again",
22 | });
23 | }
24 | } catch (e) {
25 | console.log(e);
26 |
27 | return NextResponse.json({
28 | success: false,
29 | message: "Something goes wrong !Please try again",
30 | });
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/src/app/api/project/add/route.js:
--------------------------------------------------------------------------------
1 | import connectToDB from "@/database";
2 | import Project from "@/models/Project";
3 | import { NextResponse } from "next/server";
4 |
5 | export const dynamic = "force-dynamic";
6 |
7 | export async function POST(req) {
8 | try {
9 | await connectToDB();
10 | const extractData = await req.json();
11 | const saveData = await Project.create(extractData);
12 |
13 | if (saveData) {
14 | return NextResponse.json({
15 | success: true,
16 | message: "Data saved successfully",
17 | });
18 | } else {
19 | return NextResponse.json({
20 | success: false,
21 | message: "Something goes wrong !Please try again",
22 | });
23 | }
24 | } catch (e) {
25 | console.log(e);
26 |
27 | return NextResponse.json({
28 | success: false,
29 | message: "Something goes wrong !Please try again",
30 | });
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/src/app/api/education/add/route.js:
--------------------------------------------------------------------------------
1 | import connectToDB from "@/database";
2 | import Education from "@/models/Education";
3 | import { NextResponse } from "next/server";
4 |
5 | export const dynamic = "force-dynamic";
6 |
7 | export async function POST(req) {
8 | try {
9 | await connectToDB();
10 | const extractData = await req.json();
11 | const saveData = await Education.create(extractData);
12 |
13 | if (saveData) {
14 | return NextResponse.json({
15 | success: true,
16 | message: "Data saved successfully",
17 | });
18 | } else {
19 | return NextResponse.json({
20 | success: false,
21 | message: "Something goes wrong !Please try again",
22 | });
23 | }
24 | } catch (e) {
25 | console.log(e);
26 |
27 | return NextResponse.json({
28 | success: false,
29 | message: "Something goes wrong !Please try again",
30 | });
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/src/app/api/experience/add/route.js:
--------------------------------------------------------------------------------
1 | import connectToDB from "@/database";
2 | import Experience from "@/models/Experience";
3 | import { NextResponse } from "next/server";
4 |
5 | export const dynamic = "force-dynamic";
6 |
7 | export async function POST(req) {
8 | try {
9 | await connectToDB();
10 | const extractData = await req.json();
11 | const saveData = await Experience.create(extractData);
12 |
13 | if (saveData) {
14 | return NextResponse.json({
15 | success: true,
16 | message: "Data saved successfully",
17 | });
18 | } else {
19 | return NextResponse.json({
20 | success: false,
21 | message: "Something goes wrong !Please try again",
22 | });
23 | }
24 | } catch (e) {
25 | console.log(e);
26 |
27 | return NextResponse.json({
28 | success: false,
29 | message: "Something goes wrong !Please try again",
30 | });
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/src/components/admin-view/login/index.js:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import FormControls from "../form-controls";
4 |
5 | const controls = [
6 | {
7 | name: "username",
8 | placeholder: "Enter User name",
9 | type: "text",
10 | label: "Enter User name",
11 | },
12 | {
13 | name: "password",
14 | placeholder: "Enter Password",
15 | type: "password",
16 | label: "Enter Password",
17 | },
18 | ];
19 |
20 | export default function Login({ formData, setFormData, handleLogin }) {
21 | return (
22 |
23 |
24 |
29 |
35 |
36 |
37 | );
38 | }
39 |
--------------------------------------------------------------------------------
/src/components/admin-view/home/index.js:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import FormControls from "../form-controls";
4 |
5 | const controls = [
6 | {
7 | name: "heading",
8 | placeholder: "Enter heading text",
9 | type: "text",
10 | label: "Enter heading text",
11 | },
12 | {
13 | name: "summary",
14 | placeholder: "Enter Career summary",
15 | type: "text",
16 | label: "Enter Career summary",
17 | },
18 | ];
19 |
20 | export default function AdminHomeView({ formData, setFormData, handleSaveData }) {
21 | console.log(formData);
22 | return (
23 |
24 |
25 |
30 |
33 |
34 |
35 | );
36 | }
37 |
--------------------------------------------------------------------------------
/src/app/api/home/update/route.js:
--------------------------------------------------------------------------------
1 | import connectToDB from "@/database";
2 | import About from "@/models/About";
3 | import Home from "@/models/Home";
4 | import { NextResponse } from "next/server";
5 |
6 | export const dynamic = "force-dynamic";
7 |
8 | export async function PUT(req) {
9 | try {
10 | await connectToDB();
11 |
12 | const extractData = await req.json();
13 | const { _id, heading, summary } = extractData;
14 |
15 | const updateData = await Home.findOneAndUpdate(
16 | {
17 | _id: _id,
18 | },
19 | { heading, summary },
20 | { new: true }
21 | );
22 |
23 | if (updateData) {
24 | return NextResponse.json({
25 | success: true,
26 | message: "updated successfully",
27 | });
28 | } else {
29 | return NextResponse.json({
30 | success: false,
31 | message: "Something went wrong !Please try again",
32 | });
33 | }
34 | } catch (e) {
35 | console.log(e);
36 | return NextResponse.json({
37 | success: false,
38 | message: "Something went wrong !Please try again",
39 | });
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/src/app/api/about/update/route.js:
--------------------------------------------------------------------------------
1 | import connectToDB from "@/database";
2 | import About from "@/models/About";
3 | import { NextResponse } from "next/server";
4 |
5 | export const dynamic = "force-dynamic";
6 |
7 | export async function PUT(req) {
8 | try {
9 | await connectToDB();
10 |
11 | const extractData = await req.json();
12 | const {
13 | _id,
14 | aboutme,
15 | noofprojects,
16 | yearofexperience,
17 | nooflclients,
18 | skills,
19 | } = extractData;
20 |
21 | const updateData = await About.findOneAndUpdate(
22 | {
23 | _id: _id,
24 | },
25 | { aboutme, noofprojects, yearofexperience, nooflclients, skills },
26 | { new: true }
27 | );
28 |
29 | if (updateData) {
30 | return NextResponse.json({
31 | success: true,
32 | message: "updated successfully",
33 | });
34 | } else {
35 | return NextResponse.json({
36 | success: false,
37 | message: "Something went wrong !Please try again",
38 | });
39 | }
40 | } catch (e) {
41 | console.log(e);
42 | return NextResponse.json({
43 | success: false,
44 | message: "Something went wrong !Please try again",
45 | });
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/src/app/api/login/route.js:
--------------------------------------------------------------------------------
1 | import connectToDB from "@/database";
2 | import User from "@/models/User";
3 | import { compare, hash } from "bcryptjs";
4 | import { NextResponse } from "next/server";
5 |
6 | export const dynamic = "force-dynamic";
7 |
8 | export async function POST(req) {
9 | try {
10 | await connectToDB();
11 | const { username, password } = await req.json();
12 |
13 | const checkUser = await User.findOne({ username });
14 |
15 | if (!checkUser) {
16 | return NextResponse.json({
17 | success: false,
18 | message: "User name is not present !Please try again",
19 | });
20 | }
21 |
22 | const hashPassword = await hash(checkUser.password, 12);
23 | const checkPassword = await compare(password, hashPassword);
24 |
25 | if (!checkPassword) {
26 | return NextResponse.json({
27 | success: false,
28 | message: "Wrong password. Please try again",
29 | });
30 | }
31 | return NextResponse.json({
32 | success: true,
33 | message: "Login successfull",
34 | });
35 | } catch (e) {
36 | console.log(e);
37 |
38 | return NextResponse.json({
39 | success: false,
40 | message: "Something goes wrong !Please try again",
41 | });
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/public/next.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/components/admin-view/about/index.js:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import FormControls from "../form-controls";
4 |
5 | const controls = [
6 | {
7 | name: "aboutme",
8 | placeholder: "About Me",
9 | type: "text",
10 | label: "About Me",
11 | },
12 | {
13 | name: "noofprojects",
14 | placeholder: "No of projects",
15 | type: "text",
16 | label: "Enter no of projects",
17 | },
18 | {
19 | name: "yearofexperience",
20 | placeholder: "No of experience",
21 | type: "text",
22 | label: "Enter no of experience",
23 | },
24 | {
25 | name: "noofclients",
26 | placeholder: "No of clients",
27 | type: "text",
28 | label: "Enter no of clients",
29 | },
30 | {
31 | name: "skills",
32 | placeholder: "skills",
33 | type: "text",
34 | label: "Skills",
35 | },
36 | ];
37 |
38 | export default function AdminAboutView({formData, setFormData , handleSaveData}) {
39 | return (
40 |
41 |
42 |
47 |
50 |
51 |
52 | );
53 | }
54 |
--------------------------------------------------------------------------------
/src/components/admin-view/education/index.js:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import FormControls from "../form-controls";
4 |
5 |
6 | const controls = [
7 | {
8 | name: "degree",
9 | placeholder: "Degree Name",
10 | type: "text",
11 | label: "Enter Degree Name",
12 | },
13 | {
14 | name: "year",
15 | placeholder: "Year",
16 | type: "text",
17 | label: "Year",
18 | },
19 | {
20 | name: "college",
21 | placeholder: "College Name",
22 | type: "text",
23 | label: "Enter College Name",
24 | },
25 | ];
26 |
27 |
28 | export default function AdminEducationView({handleSaveData, formData, setFormData , data}) {
29 | return
30 |
31 |
32 | {data && data.length
33 | ? data.map((item) => (
34 |
35 |
{item.degree}
36 |
{item.college}
37 |
{item.year}
38 |
39 | ))
40 | : null}
41 |
42 |
47 |
50 |
51 |
52 | }
53 |
--------------------------------------------------------------------------------
/src/app/page.js:
--------------------------------------------------------------------------------
1 | import ClientAboutView from "@/components/client-view/about";
2 | import ClientContactView from "@/components/client-view/contact";
3 | import ClientExperienceAndEducationView from "@/components/client-view/experience";
4 | import ClientHomeView from "@/components/client-view/home";
5 | import ClientProjectView from "@/components/client-view/project";
6 |
7 | async function extractAllDatas(currentSection) {
8 | const res = await fetch(`http://localhost:3000/api/${currentSection}/get`, {
9 | method: "GET",
10 | cache: "no-store",
11 | });
12 |
13 | const data = await res.json();
14 |
15 | return data && data.data;
16 | }
17 |
18 | export default async function Home() {
19 | const homeSectionData = await extractAllDatas("home");
20 | const aboutSectionData = await extractAllDatas("about");
21 | const experienceSectionData = await extractAllDatas("experience");
22 | const educationSectionData = await extractAllDatas("education");
23 | const projectSectionData = await extractAllDatas("project");
24 |
25 | return (
26 |
27 |
28 |
33 |
37 |
38 |
39 |
40 | );
41 | }
42 |
--------------------------------------------------------------------------------
/src/services/index.js:
--------------------------------------------------------------------------------
1 | export async function addData(currentTab, formData) {
2 | try {
3 | const response = await fetch(`/api/${currentTab}/add`, {
4 | method: "POST",
5 | headers: {
6 | "Content-Type": "application/json",
7 | },
8 | body: JSON.stringify(formData),
9 | });
10 |
11 | const result = await response.json();
12 |
13 | return result;
14 | } catch (e) {
15 | console.log(e);
16 | }
17 | }
18 |
19 | export async function getData(currentTab) {
20 | try {
21 | const response = await fetch(`/api/${currentTab}/get`, {
22 | method: "GET",
23 | });
24 |
25 | const result = await response.json();
26 |
27 | return result;
28 | } catch (e) {
29 | console.log(e);
30 | }
31 | }
32 |
33 | export async function updateData(currentTab, formData) {
34 | try {
35 | const response = await fetch(`/api/${currentTab}/update`, {
36 | method: "PUT",
37 | headers: {
38 | "Content-Type": "application/json",
39 | },
40 | body: JSON.stringify(formData),
41 | });
42 |
43 | const result = await response.json();
44 |
45 | return result;
46 | } catch (e) {
47 | console.log(e);
48 | }
49 | }
50 |
51 | export async function login(formData) {
52 | try {
53 | const response = await fetch(`/api/login`, {
54 | method: "POST",
55 | headers: {
56 | "Content-Type": "application/json",
57 | },
58 | body: JSON.stringify(formData),
59 | });
60 |
61 | const result = await response.json();
62 |
63 | return result;
64 | } catch (e) {
65 | console.log(e);
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app).
2 |
3 | ## Getting Started
4 |
5 | First, run the development server:
6 |
7 | ```bash
8 | npm run dev
9 | # or
10 | yarn dev
11 | # or
12 | pnpm dev
13 | ```
14 |
15 | Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
16 |
17 | You can start editing the page by modifying `app/page.js`. The page auto-updates as you edit the file.
18 |
19 | This project uses [`next/font`](https://nextjs.org/docs/basic-features/font-optimization) to automatically optimize and load Inter, a custom Google Font.
20 |
21 | ## Learn More
22 |
23 | To learn more about Next.js, take a look at the following resources:
24 |
25 | - [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
26 | - [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
27 |
28 | You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome!
29 |
30 | ## Deploy on Vercel
31 |
32 | The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.
33 |
34 | Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details.
35 | @emotion/react @emotion/styled @fullhuman/postcss-purgecss @mui/lab @mui/material bcryptjs framer-motion mongoose react-slick react-scroll
36 |
37 |
38 |
--------------------------------------------------------------------------------
/src/components/admin-view/project/index.js:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import FormControls from "../form-controls";
4 |
5 | const controls = [
6 | {
7 | name: "name",
8 | placeholder: "Project Name",
9 | type: "text",
10 | label: "Project Name",
11 | },
12 | {
13 | name: "technologies",
14 | placeholder: "Enter Technologies",
15 | type: "text",
16 | label: "Enter Technologies",
17 | },
18 | {
19 | name: "website",
20 | placeholder: "Website",
21 | type: "text",
22 | label: "Website",
23 | },
24 | {
25 | name: "github",
26 | placeholder: "Github",
27 | type: "text",
28 | label: "github",
29 | },
30 | ];
31 |
32 | export default function AdminProjectView({ formData, setFormData , handleSaveData , data }) {
33 | return (
34 |
35 |
36 |
37 | {data && data.length
38 | ? data.map((item) => (
39 |
40 |
{item.name}
41 |
{item.technologies}
42 |
{item.website}
43 |
{item.github}
44 |
45 | ))
46 | : null}
47 |
48 |
53 |
56 |
57 |
58 | );
59 | }
60 |
--------------------------------------------------------------------------------
/tailwind.config.js:
--------------------------------------------------------------------------------
1 | /** @type {import('tailwindcss').Config} */
2 | module.exports = {
3 | content: [
4 | './src/pages/**/*.{js,ts,jsx,tsx,mdx}',
5 | './src/components/**/*.{js,ts,jsx,tsx,mdx}',
6 | './src/app/**/*.{js,ts,jsx,tsx,mdx}',
7 | ],
8 | theme: {
9 | boxShadow: {
10 | sm: "0 1px 2px 0 rgba(0, 0, 0, 0.05)",
11 | DEFAULT:
12 | "0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06)",
13 | md: "0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06)",
14 | lg: "0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05)",
15 | xl: "0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04)",
16 | t: "0 -1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06)",
17 | orange: "0px 20px 20px -15px rgba(245,56,56,0.81) ",
18 | "green-md": "0px 20px 40px -15px rgba(245,56,56,0.81) ",
19 | "green-md" : "0px 20px 40px -15px rgba(13, 183, 96, 0.81)",
20 | none: "none",
21 | },
22 | colors: {
23 | transparent: "transparent",
24 | black: {
25 | 900 : "#000000",
26 | 500: "#4F5665",
27 | 600: "#0B132A",
28 | },
29 | orange: {
30 | 100: "#FFECEC",
31 | 500: "#F53855",
32 | },
33 | green: {
34 | 500: "#2FAB73",
35 | main : "#0DB760"
36 | },
37 | white: {
38 | 300: "#F8F8F8",
39 | 500: "#fff",
40 | },
41 | gray: {
42 | 100: "#EEEFF2",
43 | 400: "#AFB5C0",
44 | 500: "#DDDDDD",
45 | },
46 | },
47 | extend: {},
48 | },
49 | variants: {
50 | extend: {
51 | boxShadow: ["active", "hover"],
52 | },
53 | },
54 | plugins: [],
55 | }
56 |
--------------------------------------------------------------------------------
/src/components/admin-view/experience/index.js:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import FormControls from "../form-controls";
4 |
5 | const controls = [
6 | {
7 | name: "position",
8 | placeholder: "Position",
9 | type: "text",
10 | label: "Position",
11 | },
12 | {
13 | name: "company",
14 | placeholder: "Company",
15 | type: "text",
16 | label: "Company",
17 | },
18 | {
19 | name: "duration",
20 | placeholder: "Duration",
21 | type: "text",
22 | label: "Duration",
23 | },
24 | {
25 | name: "location",
26 | placeholder: "Location",
27 | type: "text",
28 | label: "Location",
29 | },
30 | {
31 | name: "jobprofile",
32 | placeholder: "Job Profile",
33 | type: "text",
34 | label: "Job Profile",
35 | },
36 | ];
37 |
38 | export default function AdminExperienceView({
39 | formData,
40 | handleSaveData,
41 | setFormData,
42 | data,
43 | }) {
44 | return (
45 |
46 |
47 |
48 | {data && data.length
49 | ? data.map((item) => (
50 |
51 |
{item.position}
52 |
{item.company}
53 |
{item.duration}
54 |
{item.location}
55 |
{item.jobprofile}
56 |
57 | ))
58 | : null}
59 |
60 |
65 |
71 |
72 |
73 | );
74 | }
75 |
--------------------------------------------------------------------------------
/src/app/globals.css:
--------------------------------------------------------------------------------
1 |
2 | /* purgecss start ignore */
3 |
4 | @tailwind base;
5 | @tailwind components;
6 |
7 | html {
8 | font-family: "Rubik", sans-serif;
9 | }
10 | body {
11 | background: bg-white-500
12 | }
13 | p {
14 | color: #000000
15 | }
16 | .animation-hover:after {
17 | background: none repeat scroll 0 0 transparent;
18 | content: "";
19 | height: 2px;
20 | transition: width 0.3s ease 0s, left 0.3s ease 0s;
21 | @apply w-0 bg-green-main left-1/2 block bottom-0 absolute;
22 | }
23 | .animation-active:after {
24 | @apply left-0 w-full;
25 | }
26 | .animation-hover:hover:after {
27 | @apply left-0 w-full;
28 | }
29 |
30 | li.custom-list:before {
31 | content: "\2022"; /* bullet point, for screen readers */
32 | text-indent: -9999999px; /* move the bullet point out of sight */
33 |
34 | width: 0.4em;
35 | height: 1em;
36 | background-repeat: no-repeat;
37 |
38 | background-size: 0.4em 0.7em;
39 | background-position: 0 0.3em;
40 | font-size: 300%;
41 | top: -0.35em;
42 | @apply absolute block;
43 | }
44 | li.circle-check:before {
45 | background-image: url("/assets/Icon/checklist.svg");
46 | left: -0.7em;
47 | top: -0.4em;
48 | }
49 | li.check:before {
50 | left: -0.5em;
51 | background-image: url("/assets/Icon/jam_check.svg");
52 | top: -0.5em;
53 | font-size: 400%;
54 | }
55 | /* Slideshow */
56 | .slick-dots li {
57 | @apply inline-block;
58 | }
59 | .slick-dots span {
60 | @apply bg-gray-500;
61 | }
62 | .slick-dots .slick-active span {
63 | @apply bg-orange-500 rounded-l-full rounded-r-full w-12;
64 | }
65 |
66 | /* purgecss end ignore */
67 | @tailwind utilities;
68 | /* purgecss start ignore */
69 | /* purgecss end ignore */
70 |
71 | body::-webkit-scrollbar {
72 | width: 5px;
73 | }
74 |
75 | body::-webkit-scrollbar-track {
76 | box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3);
77 | }
78 |
79 | body::-webkit-scrollbar-thumb {
80 | background-color: darkgrey;
81 | outline: 1px solid slategrey;
82 | }
83 |
84 | .progress-bar {
85 | position: fixed;
86 | top: 0;
87 | left: 0;
88 | right: 0;
89 | height: 10px;
90 | background: var(--red);
91 | transform-origin: 0%;
92 | }
93 |
94 | .project-wrapper{
95 | display: flex;
96 | list-style: none;
97 | height: 350px;
98 | overflow-x: scroll;
99 | padding: 20px 0;
100 | flex: 0 0 600px;
101 | }
102 |
103 | .project-wrapper li {
104 | flex: 0 0 300px;
105 | margin: 0 20px 0 0;
106 | }
107 |
108 | .project-wrapper li:last-of-type {
109 | margin: 0;
110 | }
111 |
112 | .bg {
113 | stroke: #fff;
114 | opacity: 0.3;
115 | }
116 |
117 | ::-webkit-scrollbar {
118 | height: 5px;
119 | width: 5px;
120 | background: #fff3;
121 | -webkit-border-radius: 1ex;
122 | }
123 |
124 | ::-webkit-scrollbar-thumb {
125 | background: green;
126 | -webkit-border-radius: 1ex;
127 | }
128 |
129 | ::-webkit-scrollbar-corner {
130 | background: #fff3;
131 | }
132 |
133 | #progress {
134 |
135 | transform: rotate(-90deg);
136 | }
137 |
138 | circle {
139 | stroke-dashoffset: 0;
140 | stroke-width: 15%;
141 | fill: none;
142 | }
143 |
144 | .bg {
145 | stroke: blue;
146 | opacity: 0.3;
147 | }
148 |
149 | #progress .indicator {
150 | stroke: red;
151 | }
152 |
153 | .MuiTimelineItem-root::before{
154 | flex: 0 !important;
155 | }
156 |
157 | .MuiTimelineDot-root{
158 | background-color: rgba(47, 171, 115, 1) !important;
159 | }
160 |
161 | .MuiTimelineConnector-root{
162 | background-color: rgba(47, 171, 115, 1) !important;
163 | }
164 |
165 |
166 |
167 |
168 |
169 |
--------------------------------------------------------------------------------
/src/components/client-view/navbar/index.js:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import { useEffect, useState } from "react";
4 | import { Link as LinkScroll, scroller } from "react-scroll";
5 |
6 | const menuItems = [
7 | {
8 | id: "home",
9 | label: "Home",
10 | },
11 | {
12 | id: "about",
13 | label: "About",
14 | },
15 | {
16 | id: "experience",
17 | label: "Experience",
18 | },
19 | {
20 | id: "project",
21 | label: "projects",
22 | },
23 | {
24 | id: "contact",
25 | label: "Contact",
26 | },
27 | ];
28 |
29 | function CreateMenus({ activeLink, getMenuItems, setActiveLink }) {
30 | return getMenuItems.map((item) => (
31 | setActiveLink(item.id)}
38 | className={`px-4 py-2 mx-2 cursor-pointer animation-hover inline-block relative
39 | ${
40 | activeLink === item.id
41 | ? "text-green-main animation-active shadow-green-main"
42 | : "text-[#000] font-bold hover:text-green-main"
43 | }
44 | `}
45 | >
46 | {item.label}
47 |
48 | ));
49 | }
50 |
51 | export default function Navbar() {
52 | const [activeLink, setActiveLink] = useState("home");
53 | const [scrollActive, setScrollActive] = useState(false);
54 |
55 | useEffect(() => {
56 | window.addEventListener("scroll", () => {
57 | setScrollActive(window.screenY > 20);
58 | });
59 | }, []);
60 |
61 | return (
62 | <>
63 |
100 |
111 | >
112 | );
113 | }
114 |
--------------------------------------------------------------------------------
/src/components/client-view/project/index.js:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import { useRef } from "react";
4 | import AnimationWrapper from "../animation-wrapper";
5 | import { motion, useScroll } from "framer-motion";
6 | import { useRouter } from "next/navigation";
7 |
8 |
9 |
10 | export default function ClientProjectView({ data }) {
11 | const containerRef = useRef(null);
12 | const { scrollXProgress } = useScroll({ container: containerRef });
13 | const router = useRouter()
14 |
15 | return (
16 |
20 |
21 |
22 |
23 | {"My Projects".split(" ").map((item, index) => (
24 |
27 | {item}{" "}
28 |
29 | ))}
30 |
31 |
48 |
49 |
50 |
51 |
52 | {data && data.length
53 | ? data.map((item, index) => (
54 | -
58 |
59 |
60 |
61 |
62 |
63 | {item.name}
64 |
65 |
66 | {item.createdAt.split("T")[0]}
67 |
68 |
69 | {item?.technologies.split(",").map((techItem) => (
70 |
71 |
74 |
75 | ))}
76 |
77 |
78 |
79 |
80 |
81 |
84 |
87 |
88 |
89 |
90 | ))
91 | : null}
92 |
93 |
94 |
95 | );
96 | }
97 |
--------------------------------------------------------------------------------
/src/components/client-view/home/index.js:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import { useMemo, useRef } from "react";
4 | import AnimationWrapper from "../animation-wrapper";
5 | import { motion } from "framer-motion";
6 | import {
7 | FaFacebookF,
8 | FaLinkedinIn,
9 | FaInstagram,
10 | FaTwitter,
11 | } from "react-icons/fa";
12 | import Image from "next/image";
13 | import aiImage from "../../../assets/ai-image.png";
14 |
15 | function variants() {
16 | return {
17 | offscreen: {
18 | y: 150,
19 | opacity: 0,
20 | },
21 | onscreen: ({ duration = 2 } = {}) => ({
22 | y: 0,
23 | opacity: 1,
24 | transition: {
25 | type: "spring",
26 | duration,
27 | },
28 | }),
29 | };
30 | }
31 |
32 | const socialIcons = [
33 | {
34 | id: "facebook",
35 | icon: (
36 |
40 | ),
41 | },
42 | {
43 | id: "twitter",
44 | icon: (
45 |
46 | ),
47 | },
48 | {
49 | id: "linkedin",
50 | icon: (
51 |
55 | ),
56 | },
57 | {
58 | id: "instagram",
59 | icon: (
60 |
64 | ),
65 | },
66 | ];
67 |
68 | export default function ClientHomeView({ data }) {
69 | console.log(data, "ClientHomeView");
70 |
71 | const setVariants = useMemo(() => variants(), []);
72 | const containerRef = useRef(null);
73 |
74 | return (
75 |
76 |
77 |
83 |
84 |
85 | {data && data.length
86 | ? data[0]?.heading
87 | .split(" ")
88 | .map((item, index) => (
89 |
96 | {item}{" "}
97 |
98 | ))
99 | : null}
100 |
101 |
102 | {data && data.length ? data[0]?.summary : null}
103 |
104 |
105 | {socialIcons.map((item) => (
106 |
119 | {item.icon}
120 |
121 | ))}
122 |
123 |
124 |
125 |
130 |
131 |
140 |
141 |
142 |
143 |
144 |
145 | );
146 | }
147 |
--------------------------------------------------------------------------------
/src/components/client-view/about/index.js:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import { useMemo } from "react";
4 | import AnimationWrapper from "../animation-wrapper";
5 | import { motion } from "framer-motion";
6 | import Image from "next/image";
7 | import aboutMeImage from "../../../assets/about-image.png";
8 |
9 | function variants() {
10 | return {
11 | offscreen: {
12 | y: 150,
13 | opacity: 0,
14 | },
15 | onscreen: ({ duration = 2 } = {}) => ({
16 | y: 0,
17 | opacity: 1,
18 | transition: {
19 | type: "spring",
20 | duration,
21 | },
22 | }),
23 | };
24 | }
25 |
26 | const skillItemVariant = {
27 | hidden: { y: 20, opacity: 0 },
28 | visible: {
29 | y: 0,
30 | opacity: 1,
31 | },
32 | };
33 |
34 | export default function ClientAboutView({ data }) {
35 | console.log(data, "aboutdata");
36 |
37 | const setVariants = useMemo(() => variants(), []);
38 |
39 | const aboutDataInfo = [
40 | {
41 | label: "Client",
42 | value: data?.noofclients || "0",
43 | },
44 | {
45 | label: "Projects",
46 | value: data?.noofprojects || "0",
47 | },
48 | {
49 | label: "Experience",
50 | value: data?.yearofexperience || "0",
51 | },
52 | ];
53 |
54 | const headingText = "Why Hire Me For Your Next Project ?";
55 |
56 | return (
57 |
58 |
59 |
60 | {aboutDataInfo.map((infoItem, index) => (
61 |
75 |
76 |
77 |
78 | {infoItem.value}+
79 |
80 |
81 | {infoItem.label}
82 |
83 |
84 |
85 |
86 | ))}
87 |
88 |
89 |
90 |
91 |
92 | {headingText.split(" ").map((item, index) => (
93 |
96 | {item}{" "}
97 |
98 | ))}
99 |
100 |
{data?.aboutme}
101 |
102 |
103 |
104 |
105 |
106 |
114 |
115 |
116 |
117 |
121 | {data?.skills.split(",").map((skill) => (
122 |
126 |
129 |
130 | ))}
131 |
132 |
133 |
134 |
135 | );
136 | }
137 |
--------------------------------------------------------------------------------
/src/components/client-view/contact/index.js:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import { useEffect, useState } from "react";
4 | import AnimationWrapper from "../animation-wrapper";
5 | import { addData } from "@/services";
6 |
7 | const controls = [
8 | {
9 | name: "name",
10 | placeholder: "Enter your name",
11 | type: "text",
12 | label: "Name",
13 | },
14 | {
15 | name: "email",
16 | placeholder: "Enter your email",
17 | type: "email",
18 | label: "Email",
19 | },
20 | {
21 | name: "message",
22 | placeholder: "Enter your message",
23 | type: "text",
24 | label: "Message",
25 | },
26 | ];
27 |
28 | const initialFormData = {
29 | name: "",
30 | email: "",
31 | message: "",
32 | };
33 |
34 | export default function ClientContactView() {
35 | const [formData, setFormData] = useState(initialFormData);
36 | const [showSuccessMessage, setShowSuccessMessage] = useState(false);
37 |
38 | async function handleSendMessage() {
39 | const res = await addData("contact", formData);
40 | console.log(res,'contact-res');
41 |
42 | if(res && res.success) {
43 | setFormData(initialFormData)
44 | setShowSuccessMessage(true)
45 | }
46 | }
47 |
48 | useEffect(()=>{
49 | if(showSuccessMessage) {
50 | setTimeout(()=>{
51 | setShowSuccessMessage(false)
52 | },1500)
53 | }
54 |
55 | },[showSuccessMessage])
56 |
57 | const isValidForm = () => {
58 | return formData &&
59 | formData.name !== "" &&
60 | formData.email !== "" &&
61 | formData.message !== ""
62 | ? true
63 | : false;
64 | };
65 |
66 | console.log(isValidForm(), 'isValidForm()');
67 |
68 | return (
69 |
150 | );
151 | }
152 |
--------------------------------------------------------------------------------
/src/components/client-view/experience/index.js:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import {
4 | Timeline,
5 | TimelineConnector,
6 | TimelineContent,
7 | TimelineDot,
8 | TimelineItem,
9 | TimelineSeparator,
10 | } from "@mui/lab";
11 | import AnimationWrapper from "../animation-wrapper";
12 | import { motion } from "framer-motion";
13 |
14 | export default function ClientExperienceAndEducationView({
15 | educationData,
16 | experienceData,
17 | }) {
18 | console.log(educationData, experienceData, "experienceData");
19 |
20 | return (
21 |
25 |
26 |
27 |
28 |
29 |
30 | {"My Experince".split(" ").map((item, index) => (
31 |
36 | {item}{" "}
37 |
38 | ))}
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 | {experienceData && experienceData.length
47 | ? experienceData.map((experienceItem) => (
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 | {experienceItem.duration}
57 |
58 |
59 | {experienceItem.company},{" "}
60 | {experienceItem.location}
61 |
62 |
63 | {experienceItem.position}
64 |
65 |
66 | {experienceItem.jobprofile}
67 |
68 |
69 |
70 |
71 | ))
72 | : null}
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 | {"My Education".split(" ").map((item, index) => (
83 |
88 | {item}{" "}
89 |
90 | ))}
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 | {educationData && educationData.length
99 | ? educationData.map((educationItem) => (
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 | {educationItem.year}
109 |
110 |
111 | {educationItem.college}
112 |
113 |
114 | {educationItem.degree}
115 |
116 |
117 |
118 |
119 | ))
120 | : null}
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 | );
129 | }
130 |
--------------------------------------------------------------------------------
/src/app/admin/page.js:
--------------------------------------------------------------------------------
1 | "use client";
2 |
3 | import AdminAboutView from "@/components/admin-view/about";
4 | import AdminContactView from "@/components/admin-view/contact";
5 | import AdminEducationView from "@/components/admin-view/education";
6 | import AdminExperienceView from "@/components/admin-view/experience";
7 | import AdminHomeView from "@/components/admin-view/home";
8 | import Login from "@/components/admin-view/login";
9 | import AdminProjectView from "@/components/admin-view/project";
10 | import { addData, getData, login, updateData } from "@/services";
11 | import { useEffect, useState } from "react";
12 |
13 | const initialHomeFormData = {
14 | heading: "",
15 | summary: "",
16 | };
17 |
18 | const initialAboutFormData = {
19 | aboutme: "",
20 | noofprojects: "",
21 | yearofexperience: "",
22 | noofclients: "",
23 | skills: "",
24 | };
25 |
26 | const initialExperienceFormData = {
27 | position: "",
28 | company: "",
29 | duration: "",
30 | location: "",
31 | jobprofile: "",
32 | };
33 |
34 | const initialEducationFormData = {
35 | degree: "",
36 | year: "",
37 | college: "",
38 | };
39 |
40 | const initialProjectFormData = {
41 | name: "",
42 | website: "",
43 | technologies: "",
44 | github: "",
45 | };
46 |
47 | const initialLoginFormData = {
48 | username: "",
49 | password: "",
50 | };
51 |
52 | export default function AdminView() {
53 | const [currentSelectedTab, setCurrentSelectedTab] = useState("home");
54 | const [homeViewFormData, setHomeViewFormData] = useState(initialHomeFormData);
55 | const [aboutViewFormData, setAboutViewFormData] =
56 | useState(initialAboutFormData);
57 | const [experienceViewFormData, setExperienceViewFormData] = useState(
58 | initialExperienceFormData
59 | );
60 | const [educationViewFormData, setEducationViewFormData] = useState(
61 | initialEducationFormData
62 | );
63 | const [projectViewFormData, setProjectViewFormData] = useState(
64 | initialProjectFormData
65 | );
66 |
67 |
68 | const [allData, setAllData] = useState({});
69 | const [update, setUpdate] = useState(false);
70 | const [authUser, setAuthUser] = useState(false);
71 | const [loginFormData, setLoginFormData] = useState(initialLoginFormData);
72 |
73 | const menuItems = [
74 | {
75 | id: "home",
76 | label: "Home",
77 | component: (
78 |
83 | ),
84 | },
85 | {
86 | id: "about",
87 | label: "About",
88 | component: (
89 |
94 | ),
95 | },
96 | {
97 | id: "experience",
98 | label: "Experience",
99 | component: (
100 |
106 | ),
107 | },
108 | {
109 | id: "education",
110 | label: "Education",
111 | component: (
112 |
118 | ),
119 | },
120 | {
121 | id: "project",
122 | label: "Project",
123 | component: (
124 |
130 | ),
131 | },
132 | {
133 | id: "contact",
134 | label: "Contact",
135 | component: ,
138 | },
139 | ];
140 |
141 | async function extractAllDatas() {
142 | const response = await getData(currentSelectedTab);
143 |
144 | if (
145 | currentSelectedTab === "home" &&
146 | response &&
147 | response.data &&
148 | response.data.length
149 | ) {
150 | setHomeViewFormData(response && response.data[0]);
151 | setUpdate(true);
152 | }
153 |
154 | if (
155 | currentSelectedTab === "about" &&
156 | response &&
157 | response.data &&
158 | response.data.length
159 | ) {
160 | setAboutViewFormData(response && response.data[0]);
161 | setUpdate(true);
162 | }
163 |
164 | if (response?.success) {
165 | setAllData({
166 | ...allData,
167 | [currentSelectedTab]: response && response.data,
168 | });
169 | }
170 | }
171 |
172 | console.log(allData, 'allData');
173 |
174 |
175 | async function handleSaveData() {
176 | const dataMap = {
177 | home: homeViewFormData,
178 | about: aboutViewFormData,
179 | education: educationViewFormData,
180 | experience: experienceViewFormData,
181 | project: projectViewFormData,
182 | };
183 |
184 | const response = update
185 | ? await updateData(currentSelectedTab, dataMap[currentSelectedTab])
186 | : await addData(currentSelectedTab, dataMap[currentSelectedTab]);
187 | console.log(response, "response");
188 |
189 | if (response.success) {
190 | resetFormDatas();
191 | extractAllDatas();
192 | }
193 | }
194 |
195 | useEffect(() => {
196 | extractAllDatas();
197 | }, [currentSelectedTab]);
198 |
199 | function resetFormDatas() {
200 | setHomeViewFormData(initialHomeFormData);
201 | setAboutViewFormData(initialAboutFormData);
202 | setExperienceViewFormData(initialExperienceFormData);
203 | setEducationViewFormData(initialEducationFormData);
204 | setProjectViewFormData(initialProjectFormData);
205 | }
206 |
207 | console.log(allData, homeViewFormData, "homeViewFormData");
208 |
209 | useEffect(() => {
210 | setAuthUser(JSON.parse(sessionStorage.getItem("authUser")));
211 | }, []);
212 |
213 | async function handleLogin() {
214 | const res = await login(loginFormData);
215 |
216 | console.log(res, "login");
217 |
218 | if (res?.success) {
219 | setAuthUser(true);
220 | sessionStorage.setItem("authUser", JSON.stringify(true));
221 | }
222 | }
223 |
224 | if (!authUser)
225 | return (
226 |
231 | );
232 |
233 | return (
234 |
235 |
260 |
261 | {menuItems.map(
262 | (item) => item.id === currentSelectedTab && item.component
263 | )}
264 |
265 |
266 | );
267 | }
268 |
--------------------------------------------------------------------------------