├── README.md
├── one-social-media
├── .gitignore
├── README.md
├── jsconfig.json
├── next.config.mjs
├── package.json
├── pnpm-lock.yaml
├── postcss.config.js
├── public
│ ├── default_profile.jpeg
│ ├── facebook.svg
│ ├── hareesh.png
│ ├── home-hero.avif
│ ├── next copy.svg
│ ├── next.svg
│ ├── osm-white.png
│ ├── osm.png
│ ├── portFolio.png
│ ├── vercel copy.svg
│ └── vercel.svg
├── src
│ └── app
│ │ ├── Context
│ │ └── UserContest.jsx
│ │ ├── QueryProvider.js
│ │ ├── components
│ │ ├── Avatar.jsx
│ │ ├── Footer.jsx
│ │ ├── LogoPart.jsx
│ │ ├── NavBar.jsx
│ │ ├── Post
│ │ │ ├── Like.jsx
│ │ │ ├── MakePost.jsx
│ │ │ ├── Post.jsx
│ │ │ ├── PostInput.jsx
│ │ │ └── comment
│ │ │ │ ├── Comment.jsx
│ │ │ │ └── CommentInput.jsx
│ │ ├── ReplyAvatar.jsx
│ │ ├── homecomponents
│ │ │ ├── FriendRequest.jsx
│ │ │ ├── Friends.jsx
│ │ │ ├── Profile
│ │ │ │ ├── ProfileCard.jsx
│ │ │ │ ├── ProfilePhotoUpdate.jsx
│ │ │ │ ├── ViewProfile.jsx
│ │ │ │ └── profileUpdate.jsx
│ │ │ ├── Suggestion.jsx
│ │ │ └── message.jsx
│ │ ├── imagecrop
│ │ │ ├── canvasPreview.jsx
│ │ │ ├── crop.jsx
│ │ │ └── useDebounceEffect.jsx
│ │ ├── login
│ │ │ └── Main.jsx
│ │ └── useDebounceEffect.jsx
│ │ ├── data
│ │ └── Data.js
│ │ ├── favicon.ico
│ │ ├── globals.css
│ │ ├── home
│ │ └── page.jsx
│ │ ├── layout.js
│ │ ├── page.js
│ │ └── utils
│ │ └── api.js
└── tailwind.config.js
└── server
├── .gitignore
├── config.js
├── controllers
├── authController.js
├── comments.js
├── passwordReset.js
├── post.js
├── userControl.js
└── users.js
├── middleware.js
├── models
├── commentModel.js
├── emailVerificatin.js
├── passwordResetSchema.js
├── postModel.js
├── requestSchema.js
└── userModels.js
├── package.json
├── pnpm-lock.yaml
├── routes
└── auth.js
├── server.js
├── utils
├── index.js
├── passwordChange.js
├── passwordResetRequest.js
└── sendVerification.js
├── vercel.json
└── views
├── index.html
└── passwordReset.html
/README.md:
--------------------------------------------------------------------------------
1 | ## ABOUT
2 | Connecting people, new post at a time. Welcome to one social media platform for sharing moments, connecting with friends, and discovering what matters to you. Join the community today and make every day memorable.
3 |
4 | ## SAMPLE PHOTOS
5 | 
6 |
7 | 
8 |
9 | 
10 |
11 | 
12 |
--------------------------------------------------------------------------------
/one-social-media/.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 | .yarn/install-state.gz
8 |
9 | # testing
10 | /coverage
11 |
12 | # next.js
13 | /.next/
14 | /out/
15 |
16 | # production
17 | /build
18 |
19 | # misc
20 | .DS_Store
21 | *.pem
22 |
23 | # debug
24 | npm-debug.log*
25 | yarn-debug.log*
26 | yarn-error.log*
27 |
28 | # local env files
29 | .env*.local
30 | .env
31 |
32 | # vercel
33 | .vercel
34 |
35 | # typescript
36 | *.tsbuildinfo
37 | next-env.d.ts
38 |
--------------------------------------------------------------------------------
/one-social-media/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 | # or
14 | bun dev
15 | ```
16 |
17 | Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
18 |
19 | You can start editing the page by modifying `app/page.js`. The page auto-updates as you edit the file.
20 |
21 | This project uses [`next/font`](https://nextjs.org/docs/basic-features/font-optimization) to automatically optimize and load Inter, a custom Google Font.
22 |
23 | ## Learn More
24 |
25 | To learn more about Next.js, take a look at the following resources:
26 |
27 | - [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
28 | - [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
29 |
30 | You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome!
31 |
32 | ## Deploy on Vercel
33 |
34 | 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.
35 |
36 | Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details.
37 |
--------------------------------------------------------------------------------
/one-social-media/jsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "paths": {
4 | "@/*": ["./src/*"]
5 | }
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/one-social-media/next.config.mjs:
--------------------------------------------------------------------------------
1 | /** @type {import('next').NextConfig} */
2 | const nextConfig = {};
3 |
4 | export default nextConfig;
5 |
--------------------------------------------------------------------------------
/one-social-media/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "one-social-media",
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.3",
13 | "@emotion/styled": "^11.11.0",
14 | "@mui/icons-material": "^5.15.6",
15 | "@mui/material": "^5.15.6",
16 | "@tanstack/react-query": "^5.17.19",
17 | "@tanstack/react-query-devtools": "^5.17.21",
18 | "axios": "^1.6.6",
19 | "next": "14.1.0",
20 | "notistack": "^3.0.1",
21 | "react": "^18",
22 | "react-dom": "^18",
23 | "react-icons": "^5.0.1",
24 | "react-image-crop": "^11.0.5",
25 | "socket.io-client": "^4.7.4",
26 | "ws": "^8.16.0"
27 | },
28 | "devDependencies": {
29 | "autoprefixer": "^10.0.1",
30 | "postcss": "^8",
31 | "tailwindcss": "^3.3.0"
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/one-social-media/postcss.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | plugins: {
3 | tailwindcss: {},
4 | autoprefixer: {},
5 | },
6 | };
7 |
--------------------------------------------------------------------------------
/one-social-media/public/default_profile.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HareeshDhruva/osm/a227fa46f76bf4cdac4e7f6f622b48c9417c3511/one-social-media/public/default_profile.jpeg
--------------------------------------------------------------------------------
/one-social-media/public/facebook.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/one-social-media/public/hareesh.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HareeshDhruva/osm/a227fa46f76bf4cdac4e7f6f622b48c9417c3511/one-social-media/public/hareesh.png
--------------------------------------------------------------------------------
/one-social-media/public/home-hero.avif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HareeshDhruva/osm/a227fa46f76bf4cdac4e7f6f622b48c9417c3511/one-social-media/public/home-hero.avif
--------------------------------------------------------------------------------
/one-social-media/public/next copy.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/one-social-media/public/next.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/one-social-media/public/osm-white.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HareeshDhruva/osm/a227fa46f76bf4cdac4e7f6f622b48c9417c3511/one-social-media/public/osm-white.png
--------------------------------------------------------------------------------
/one-social-media/public/osm.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HareeshDhruva/osm/a227fa46f76bf4cdac4e7f6f622b48c9417c3511/one-social-media/public/osm.png
--------------------------------------------------------------------------------
/one-social-media/public/portFolio.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HareeshDhruva/osm/a227fa46f76bf4cdac4e7f6f622b48c9417c3511/one-social-media/public/portFolio.png
--------------------------------------------------------------------------------
/one-social-media/public/vercel copy.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/one-social-media/public/vercel.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/one-social-media/src/app/Context/UserContest.jsx:
--------------------------------------------------------------------------------
1 | "use client";
2 | import { createContext, useState } from "react";
3 | export const UserContest = createContext(null);
4 |
5 | function PhotoContestProvider({ children }) {
6 | const [photo, setPhoto] = useState(0);
7 | const [activeStep, setActiveStep] = useState(0);
8 | return (
9 |
17 | {children}
18 |
19 | );
20 | }
21 | export default PhotoContestProvider;
22 |
--------------------------------------------------------------------------------
/one-social-media/src/app/QueryProvider.js:
--------------------------------------------------------------------------------
1 | "use client";
2 | import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
3 | import { ReactQueryDevtools } from "@tanstack/react-query-devtools";
4 | import { SnackbarProvider } from "notistack";
5 | const queryClient = new QueryClient();
6 | const QueryProvider = ({ children }) => {
7 | return (
8 |
9 |
10 | {children}
11 |
12 |
13 |
14 | );
15 | };
16 |
17 | export default QueryProvider;
18 |
--------------------------------------------------------------------------------
/one-social-media/src/app/components/Avatar.jsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import { Avatar } from "@mui/material";
3 |
4 | const AvatarBlock = ({ url, data }) => {
5 | return (
6 | <>
7 |
8 |
9 |
10 |
11 | {data}
12 |
13 |
14 |
15 |
16 | >
17 | );
18 | };
19 |
20 | export default AvatarBlock;
21 |
--------------------------------------------------------------------------------
/one-social-media/src/app/components/Footer.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import { footerLinks } from '../data/Data'
3 | const Footer = () => {
4 | const date = new Date;
5 | return (
6 |
48 | )
49 | }
50 |
51 | export default Footer
52 |
--------------------------------------------------------------------------------
/one-social-media/src/app/components/LogoPart.jsx:
--------------------------------------------------------------------------------
1 | import Image from "next/image";
2 | const Leftpart = () => {
3 | return (
4 |
5 |
6 |
7 |

12 |
13 |
14 |
15 | One social media helps you connect and share with the people in your
16 | life.
17 |
18 |
19 |
20 |
21 | );
22 | };
23 | export default Leftpart;
24 |
--------------------------------------------------------------------------------
/one-social-media/src/app/components/NavBar.jsx:
--------------------------------------------------------------------------------
1 | "use client";
2 | import React, { useState } from "react";
3 | import { FiMenu } from "react-icons/fi";
4 | import { MdAccountCircle } from "react-icons/md";
5 | import { adminData, deletePost, getUser, getUserPost } from "@/app/utils/api";
6 | import Tooltip from "@mui/material/Tooltip";
7 | import Fade from "@mui/material/Fade";
8 | import Link from "next/link";
9 | import { FaUserEdit } from "react-icons/fa";
10 | import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query";
11 | import ProfileUpdate from "./homecomponents/Profile/profileUpdate";
12 | import ProfileCard from "./homecomponents/Profile/ProfileCard";
13 | import FriendRequest from "./homecomponents/FriendRequest";
14 | import Suggestion from "./homecomponents/Suggestion";
15 | import DeleteIcon from "@mui/icons-material/Delete";
16 | import IconButton from "@mui/material/IconButton";
17 | import FavoriteIcon from "@mui/icons-material/Favorite";
18 | import CloseIcon from "@mui/icons-material/Close";
19 | import {
20 | Avatar,
21 | DialogContent,
22 | Dialog,
23 | Drawer,
24 | AppBar,
25 | Toolbar,
26 | } from "@mui/material";
27 | import axios from "axios";
28 | import { useSnackbar } from "notistack";
29 |
30 | const NavBar = () => {
31 | const [userid, setUserId] = useState("");
32 | const [userWindow, setUserWindow] = useState(false);
33 | const [edit, setEdit] = useState(false);
34 | const [mini, setMini] = useState(false);
35 | const { enqueueSnackbar } = useSnackbar();
36 |
37 | const onLogout = async () => {
38 | const res = await axios.post(
39 | `${process.env.NEXT_PUBLIC_BACKEND}/logout`,
40 | {},
41 | {
42 | withCredentials: true,
43 | }
44 | );
45 | if (res.status === 200) {
46 | localStorage.clear();
47 | window.location.replace("/");
48 | }
49 | };
50 |
51 | //user
52 | const { data: Admin } = useQuery({ queryKey: ["Admin"], queryFn: adminData });
53 | const queryClient = useQueryClient();
54 |
55 | const userWindowHandle = (id) => {
56 | setUserId(id);
57 | setUserWindow(true);
58 | mutate();
59 | usePost.mutate();
60 | };
61 |
62 | const handleClose = () => {
63 | setUserWindow(false);
64 | setMini(false);
65 | };
66 | const handleOpen = () => {
67 | setEdit(true);
68 | };
69 |
70 | const { mutate, data: UserData } = useMutation({
71 | mutationFn: () => getUser(userid),
72 | onSuccess: () => {
73 | queryClient.invalidateQueries({ queryKey: ["user"] });
74 | },
75 | });
76 |
77 | let timestampStr = UserData?.DOB;
78 | let birthday;
79 | if (timestampStr) {
80 | let timestamp = new Date(timestampStr);
81 | birthday = timestamp.toISOString().split("T")[0];
82 | } else {
83 | birthday = null;
84 | }
85 |
86 | // mini
87 | const handleChangeMini = () => {
88 | setMini(true);
89 | };
90 |
91 | //delete
92 |
93 | const usePost = useMutation({
94 | mutationFn: () => getUserPost(userid),
95 | onSuccess: () => {
96 | queryClient.invalidateQueries({ queryKey: ["userPost"] });
97 | },
98 | });
99 |
100 | const deletepost = useMutation({
101 | mutationFn: (userid) => deletePost(userid),
102 | onSuccess: (message) => {
103 | queryClient.invalidateQueries({ queryKey: ["post"] });
104 | setUserWindow(false);
105 | if(message === "Delete SuccessFully"){
106 | enqueueSnackbar(message,{
107 | autoHideDuration: 2000,
108 | variant: "success",
109 | anchorOrigin: {
110 | vertical: "bottom",
111 | horizontal: "right",
112 | },
113 | preventDuplicate: false,
114 | });
115 | }
116 | else{
117 | enqueueSnackbar(message, {
118 | autoHideDuration: 2000,
119 | variant: "error",
120 | anchorOrigin: {
121 | vertical: "bottom",
122 | horizontal: "right",
123 | },
124 | preventDuplicate: false,
125 | });
126 | }
127 | }
128 | });
129 |
130 | const deletePostId = (id) => {
131 | deletepost.mutate(id);
132 | };
133 |
134 | return (
135 |
364 | );
365 | };
366 |
367 | export default NavBar;
368 |
--------------------------------------------------------------------------------
/one-social-media/src/app/components/Post/Like.jsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import { GoHeart, GoHeartFill } from "react-icons/go";
3 | import { likeAPost, adminData } from "@/app/utils/api";
4 | import { useQuery, useQueryClient, useMutation } from "@tanstack/react-query";
5 |
6 | function LikeDislike({ like, id }) {
7 | const queryClient = useQueryClient();
8 | const { data: Admin } = useQuery({ queryKey: ["Admin"], queryFn: adminData });
9 |
10 | const mutation = useMutation({
11 | mutationFn: likeAPost(id),
12 | onSuccess: () => {
13 | queryClient.invalidateQueries({ queryKey: ["post"] });
14 | },
15 | });
16 |
17 | const handleLike = () => {
18 | mutation.mutate();
19 | };
20 |
21 | return (
22 |
23 | {like.includes(Admin?._id) ? (
24 |
25 |
30 |
31 | ) : (
32 |
33 |
38 |
39 | )}
40 |
43 |
44 | );
45 | }
46 |
47 | export default LikeDislike;
48 |
--------------------------------------------------------------------------------
/one-social-media/src/app/components/Post/MakePost.jsx:
--------------------------------------------------------------------------------
1 | import React, { useContext } from "react";
2 | import { Dialog, DialogTitle, Typography, Box } from "@mui/material";
3 | import IconButton from "@mui/material/IconButton";
4 | import CloseIcon from "@mui/icons-material/Close";
5 | import ImageCrop from "../imagecrop/crop";
6 | import Stepper from "@mui/material/Stepper";
7 | import Step from "@mui/material/Step";
8 | import StepLabel from "@mui/material/StepLabel";
9 | import { UserContest } from "../../Context/UserContest";
10 | const MakePost = ({ open, setPostOpen, mode }) => {
11 | const context = useContext(UserContest);
12 |
13 | const handleClose = () => {
14 | setPostOpen(false);
15 | context.setActiveStep(0);
16 | };
17 |
18 | const steps = ["DESCRIPTION", "UPLOAD FILE", "UPLOAD"];
19 |
20 | if (context.activeStep === 3) {
21 | handleClose();
22 | }
23 |
24 | return (
25 |
66 | );
67 | };
68 |
69 | export default MakePost;
70 |
--------------------------------------------------------------------------------
/one-social-media/src/app/components/Post/Post.jsx:
--------------------------------------------------------------------------------
1 | import React, { useState } from "react";
2 | import { AiOutlineMenu } from "react-icons/ai";
3 | import "../../globals.css";
4 | import LikeDislike from "./Like";
5 | import {
6 | deletePost,
7 | getAllPost,
8 | getUser,
9 | getUserPost,
10 | sendFriendRequestMod,
11 | } from "@/app/utils/api";
12 | import Comment from "./comment/Comment";
13 | import MakePost from "./MakePost";
14 | import PostInput from "./PostInput";
15 | import Backdrop from "@mui/material/Backdrop";
16 | import CircularProgress from "@mui/material/CircularProgress";
17 | import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
18 | import axios from "axios";
19 | import { FaUserPlus } from "react-icons/fa6";
20 | import { MdOutlinePostAdd } from "react-icons/md";
21 | import IconButton from "@mui/material/IconButton";
22 | import CloseIcon from "@mui/icons-material/Close";
23 | import FavoriteIcon from "@mui/icons-material/Favorite";
24 | import { Dialog, DialogContent, AppBar, Toolbar } from "@mui/material";
25 | import DeleteIcon from "@mui/icons-material/Delete";
26 |
27 | const URL = process.env.NEXT_PUBLIC_BACKEND;
28 |
29 | const Post = () => {
30 | const [open, setOpen] = useState(false);
31 | const [postOpen, setPostOpen] = useState(false);
32 | const [id, setid] = useState("");
33 | const [mode, setMode] = useState("");
34 | const [userid, setUserId] = useState("");
35 | const [userWindow, setUserWindow] = useState(false);
36 | const [showComponent, setShowComponent] = useState("");
37 | const [friendRequestId, setFriendRequestId] = useState();
38 | const newData = { requestId: friendRequestId };
39 |
40 | const userWindowHandle = (id) => {
41 | setUserId(id);
42 | setUserWindow(true);
43 | mutate();
44 | };
45 |
46 | const handleClose = () => {
47 | setOpen(false);
48 | setUserWindow(false);
49 | };
50 | const handleOpen = (id) => {
51 | setid(id);
52 | setOpen(true);
53 | usePost.mutate(id);
54 | };
55 |
56 | const handlepostOpen = () => {
57 | setMode("MAKE POST");
58 | setPostOpen(true);
59 | };
60 |
61 | const handlepostClose = () => {
62 | setPostOpen(false);
63 | };
64 |
65 | const {
66 | data: Post,
67 | isLoading: loading,
68 | isSuccess: success,
69 | } = useQuery({ queryKey: ["post"], queryFn: getAllPost });
70 |
71 | const queryClient = useQueryClient();
72 |
73 | const { mutate, data: UserData } = useMutation({
74 | mutationFn: () => getUser(userid),
75 | onSuccess: () => {
76 | queryClient.invalidateQueries({ queryKey: ["user"] });
77 | },
78 | });
79 |
80 | let timestampStr = UserData?.DOB;
81 | let birthday;
82 | if (timestampStr) {
83 | let timestamp = new Date(timestampStr);
84 | birthday = timestamp.toISOString().split("T")[0];
85 | } else {
86 | birthday = null;
87 | }
88 |
89 | const searchUserResult = useMutation({
90 | mutationKey: ["searchUserResult"],
91 | mutationFn: async (searchData) => {
92 | const response = await axios.post(`${URL}/searchUser`, {
93 | search: searchData,
94 | });
95 | return response.data.data;
96 | },
97 | });
98 |
99 | const handleSearch = (e) => {
100 | setShowComponent(e.target.value);
101 | searchUserResult.mutate(e.target.value);
102 | };
103 |
104 | //send request
105 | const mutation = useMutation({
106 | mutationFn: () => sendFriendRequestMod(newData),
107 | onSuccess: () => {
108 | queryClient.invalidateQueries({ queryKey: ["suggestion"] });
109 | },
110 | });
111 |
112 | const sendRequest = (id) => {
113 | setFriendRequestId(id);
114 | mutation.mutate();
115 | };
116 |
117 | const usePost = useMutation({
118 | mutationFn: (newid) => getUserPost(newid),
119 | onSuccess: () => {
120 | queryClient.invalidateQueries({ queryKey: ["userPost"] });
121 | },
122 | });
123 |
124 | const deletepost = useMutation({
125 | mutationFn: (userid) => deletePost(userid),
126 | onSuccess: () => {
127 | queryClient.invalidateQueries({ queryKey: ["post"] });
128 | setUserWindow(false);
129 | },
130 | });
131 |
132 | const deletePostId = (id) => {
133 | deletepost.mutate(id);
134 | };
135 |
136 | return (
137 |
138 |
139 |
140 | {!loading && (
141 |
142 |
143 |
151 |
152 |
153 |
154 |
159 |
post
160 |
161 |
162 |
163 | {showComponent && (
164 |
165 | {searchUserResult.data && (
166 |
199 | )}
200 |
201 | )}
202 |
203 | )}
204 |
205 |
206 |
207 | {Post?.map((users) => (
208 |
209 |
userWindowHandle(users?.userId?._id)}
212 | >
213 |
214 | {users?.userId?.profileUrl ? (
215 |

219 | ) : (
220 |

224 | )}
225 |
226 | {users.userId.firstname + " " + users.userId.lastname}
227 |
228 |
229 |
232 |
233 |
234 | {users.image && (
235 |
236 |
![]()
{
238 | if (users.comments.length !== 0) {
239 | handleOpen(users._id);
240 | }
241 | }}
242 | className="flex justify-center items-center"
243 | src={users.image.url}
244 | alt="profile"
245 | />
246 |
247 | )}
248 |
249 |
250 |
251 |
252 |
253 |
254 | {"@ " +
255 | users.userId.firstname +
256 | "_" +
257 | users.userId.lastname}
258 |
259 |
260 | {" " + users.description}
261 |
262 |
263 | {users.comments.length !== 0 && (
264 |
handleOpen(users._id)}
267 | >
268 | View all {users.comments.length} comments .....{" "}
269 |
270 | )}
271 |
272 |
273 |
274 |
275 |
276 | ))}
277 |
278 |
279 |
280 |
426 |
427 |
theme.zIndex.drawer + 1 }}
429 | open={loading}
430 | onClick={success}
431 | >
432 |
433 |
434 |
435 |
436 | );
437 | };
438 |
439 | export default Post;
440 |
--------------------------------------------------------------------------------
/one-social-media/src/app/components/Post/PostInput.jsx:
--------------------------------------------------------------------------------
1 | import React, { useState } from "react";
2 | import { LuSendHorizonal } from "react-icons/lu";
3 | import { makeAComment } from "@/app/utils/api";
4 | import { useMutation, useQueryClient } from "@tanstack/react-query";
5 |
6 | const PostInput = ({ uid }) => {
7 | const [comment, setComment] = useState("");
8 | const handleChangeComment = (e) => {
9 | setComment(e.target.value);
10 | };
11 | const queryClient = useQueryClient();
12 | const mutation = useMutation({
13 | mutationFn: async () => {
14 | await makeAComment(comment, uid);
15 | },
16 | onSuccess: () => {
17 | queryClient.invalidateQueries({ queryKey: ["post"] });
18 | setComment("");
19 | },
20 | });
21 |
22 | const postman = () => {
23 | mutation.mutate();
24 | };
25 |
26 | return (
27 |
28 | {
35 | if (event.key === "Enter") postman();
36 | }}
37 | onChange={handleChangeComment}
38 | />
39 | {comment && (
40 |
47 | )}
48 |
49 | );
50 | };
51 |
52 | export default PostInput;
53 |
--------------------------------------------------------------------------------
/one-social-media/src/app/components/Post/comment/Comment.jsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import { Dialog, AppBar, Toolbar, Typography, Divider } from "@mui/material";
3 | import IconButton from "@mui/material/IconButton";
4 | import CloseIcon from "@mui/icons-material/Close";
5 | import ListItemText from "@mui/material/ListItemText";
6 | import ListItem from "@mui/material/ListItem";
7 | import List from "@mui/material/List";
8 | import AvatarBlock from "../../Avatar";
9 | import { ReplyAvatarBlock } from "../../ReplyAvatar";
10 | import CommentInput from "./CommentInput";
11 | import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query";
12 | import { getAllPost, likeAcomment } from "@/app/utils/api";
13 | import { SlLike } from "react-icons/sl";
14 |
15 | const Comment = ({ open, setOpen, id }) => {
16 | const handleClose = () => {
17 | setOpen(false);
18 | };
19 |
20 | const queryClient = useQueryClient();
21 | const { data: Post } = useQuery({ queryKey: ["post"], queryFn: getAllPost });
22 | const commentList =
23 | Post.find((item) => item._id === id && item.comments) || null;
24 |
25 | const mutation = useMutation({
26 | mutationFn: (data) => likeAcomment(data),
27 | onSuccess: () => {
28 | queryClient.invalidateQueries({ queryKey: ["post"] });
29 | },
30 | });
31 |
32 | const sendRequest = (id, rid) => {
33 | const data = { id, rid };
34 | mutation.mutate(data);
35 | };
36 |
37 | return (
38 | <>
39 | {commentList !== null && (
40 |
41 |
127 |
128 | )}
129 | >
130 | );
131 | };
132 |
133 | export default Comment;
134 |
--------------------------------------------------------------------------------
/one-social-media/src/app/components/Post/comment/CommentInput.jsx:
--------------------------------------------------------------------------------
1 | import React, { useState } from "react";
2 | import { LuSendHorizonal } from "react-icons/lu";
3 | import { adminData, replyCommentMod } from "@/app/utils/api";
4 | import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query";
5 |
6 | const CommentInput = ({ uid }) => {
7 | const [comment, setComment] = useState("");
8 | const { data: Admin } = useQuery({ queryKey: ["Admin"], queryFn: adminData });
9 | const url = Admin?.profileUrl?.url || "default_profile.jpeg";
10 | const from = Admin?.firstname + " " + Admin?.lastname;
11 |
12 | const handleChangeComment = (e) => {
13 | setComment(e.target.value);
14 | };
15 |
16 | const queryClient = useQueryClient();
17 | const mutationReply = useMutation({
18 | mutationFn: () => replyCommentMod(comment, from, url, uid),
19 | onSuccess: () => {
20 | queryClient.invalidateQueries({ queryKey: ["post"] });
21 | setComment("");
22 | },
23 | });
24 |
25 | const postman = () => {
26 | mutationReply.mutate();
27 | };
28 |
29 | return (
30 | <>
31 |
32 |
{
38 | if (event.key === "Enter") postman();
39 | }}
40 | onChange={handleChangeComment}
41 | />
42 | {comment && (
43 |
51 | )}
52 |
53 | >
54 | );
55 | };
56 |
57 | export default CommentInput;
58 |
--------------------------------------------------------------------------------
/one-social-media/src/app/components/ReplyAvatar.jsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 |
3 | export const ReplyAvatarBlock = ({ url, data }) => {
4 | return (
5 | <>
6 |
7 |
8 |

9 |
10 | {data}
11 |
12 |
13 |
14 |
15 | >
16 | );
17 | };
18 |
--------------------------------------------------------------------------------
/one-social-media/src/app/components/homecomponents/FriendRequest.jsx:
--------------------------------------------------------------------------------
1 | "use client";
2 | import React, { useState } from "react";
3 | import {
4 | deletePost,
5 | friendRequestAcceptMode,
6 | friendRequestMode,
7 | getUser,
8 | getUserPost,
9 | } from "@/app/utils/api";
10 | import { FaUserCheck } from "react-icons/fa6";
11 | import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query";
12 | import IconButton from "@mui/material/IconButton";
13 | import CloseIcon from "@mui/icons-material/Close";
14 | import FavoriteIcon from "@mui/icons-material/Favorite";
15 | import { Dialog, DialogContent, AppBar, Toolbar } from "@mui/material";
16 | import DeleteIcon from "@mui/icons-material/Delete";
17 | import { useSnackbar } from "notistack";
18 |
19 | const FriendRequest = () => {
20 | const [id, setId] = useState("");
21 | const newData = { rid: id, requestStatus: "Pending" };
22 | const { enqueueSnackbar } = useSnackbar();
23 |
24 | const { data: Request } = useQuery({
25 | queryKey: ["friendRequest"],
26 | queryFn: friendRequestMode,
27 | });
28 | const queryClient = useQueryClient();
29 |
30 | const friendRequestMutation = useMutation({
31 | mutationFn: () => friendRequestAcceptMode(newData),
32 | onSuccess: (message) => {
33 | queryClient.invalidateQueries({ queryKey: ["friendRequest"] });
34 | queryClient.invalidateQueries({ queryKey: ["Admin"] });
35 | enqueueSnackbar(message, {
36 | autoHideDuration: 3000,
37 | variant: "success",
38 | anchorOrigin: {
39 | vertical: "bottom",
40 | horizontal: "right",
41 | },
42 | });
43 | },
44 | });
45 |
46 | const readyToAccept = (id) => {
47 | setId(id);
48 | friendRequestMutation.mutate();
49 | };
50 |
51 | //user
52 | const [userid, setUserId] = useState("");
53 | const [userWindow, setUserWindow] = useState(false);
54 |
55 | const userWindowHandle = (id) => {
56 | setUserId(id);
57 | setUserWindow(true);
58 | mutate();
59 | usePost.mutate(id);
60 | };
61 |
62 | const handleClose = () => {
63 | setUserWindow(false);
64 | };
65 |
66 | const { mutate, data: UserData } = useMutation({
67 | mutationFn: () => getUser(userid),
68 | onSuccess: () => {
69 | queryClient.invalidateQueries({ queryKey: ["user"] });
70 | },
71 | });
72 |
73 | let timestampStr = UserData?.DOB;
74 | let birthday;
75 | if (timestampStr) {
76 | let timestamp = new Date(timestampStr);
77 | birthday = timestamp.toISOString().split("T")[0];
78 | } else {
79 | birthday = null;
80 | }
81 |
82 | const usePost = useMutation({
83 | mutationFn: (userid) => getUserPost(userid),
84 | onSuccess: () => {
85 | queryClient.invalidateQueries({ queryKey: ["userPost"] });
86 | },
87 | });
88 |
89 | const deletepost = useMutation({
90 | mutationFn: (userid) => deletePost(userid),
91 | onSuccess: () => {
92 | queryClient.invalidateQueries({ queryKey: ["post"] });
93 | setUserWindow(false);
94 | },
95 | });
96 |
97 | const deletePostId = (id) => {
98 | deletepost.mutate(id);
99 | };
100 |
101 | return (
102 |
103 |
104 | Friend Request
105 |
106 |
107 |
108 |
109 | {Request &&
110 | Request.map((friend) => (
111 |
112 |
userWindowHandle(friend.requestFrom._id)}
115 | >
116 | {friend?.requestFrom?.profileUrl?.url ? (
117 |

122 | ) : (
123 |

128 | )}
129 |
130 | {friend.requestFrom.firstname +
131 | " " +
132 | friend.requestFrom.lastname}
133 |
134 |
135 |
136 | readyToAccept(friend._id)} />
137 |
138 |
139 | ))}
140 |
141 |
142 |
143 |
286 |
287 | );
288 | };
289 |
290 | export default FriendRequest;
291 |
--------------------------------------------------------------------------------
/one-social-media/src/app/components/homecomponents/Friends.jsx:
--------------------------------------------------------------------------------
1 | "use client";
2 | import React, { useState } from "react";
3 | import { FaUserXmark } from "react-icons/fa6";
4 | import { adminData, deleteFriend, deletePost, getUser, getUserPost } from "@/app/utils/api";
5 | import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
6 | import IconButton from "@mui/material/IconButton";
7 | import CloseIcon from "@mui/icons-material/Close";
8 | import FavoriteIcon from "@mui/icons-material/Favorite";
9 | import { Dialog, DialogContent, AppBar, Toolbar } from "@mui/material";
10 | import DeleteIcon from "@mui/icons-material/Delete";
11 | import { useSnackbar } from "notistack";
12 |
13 | const Friends = () => {
14 | const { data: Admin } = useQuery({ queryKey: ["Admin"], queryFn: adminData });
15 | const friends = Admin?.friends;
16 |
17 | const [userid, setUserId] = useState("");
18 | const [userWindow, setUserWindow] = useState(false);
19 | const { enqueueSnackbar } = useSnackbar();
20 |
21 | const userWindowHandle = (id) => {
22 | setUserId(id);
23 | setUserWindow(true);
24 | mutate();
25 | userPost.mutate(id);
26 | };
27 |
28 | const handleClose = () => {
29 | setUserWindow(false);
30 | };
31 |
32 | const queryClient = useQueryClient();
33 |
34 | const { mutate, data: UserData } = useMutation({
35 | mutationFn: () => getUser(userid),
36 | onSuccess: () => {
37 | queryClient.invalidateQueries({ queryKey: ["user"] });
38 | },
39 | });
40 |
41 | let timestampStr = UserData?.DOB;
42 | let birthday;
43 | if (timestampStr) {
44 | let timestamp = new Date(timestampStr);
45 | birthday = timestamp.toISOString().split("T")[0];
46 | } else {
47 | birthday = null;
48 | }
49 |
50 | const userPost = useMutation({
51 | mutationFn: (userid) => getUserPost(userid),
52 | onSuccess: () => {
53 | queryClient.invalidateQueries({ queryKey: ["userPost"] });
54 | },
55 | });
56 |
57 | const deletepost = useMutation({
58 | mutationFn: (userid) => deletePost(userid),
59 | onSuccess: () => {
60 | queryClient.invalidateQueries({ queryKey: ["post"] });
61 | setUserWindow(false);
62 | },
63 | });
64 |
65 | const deletePostId = (id) => {
66 | deletepost.mutate(id);
67 | };
68 |
69 | const deletfriend = useMutation({
70 | mutationFn: (userid) => deleteFriend(userid),
71 | onSuccess: (message) => {
72 | queryClient.invalidateQueries({ queryKey: ["Admin"] });
73 | enqueueSnackbar(message,{
74 | autoHideDuration: 2000,
75 | variant: "success",
76 | anchorOrigin: {
77 | vertical: "bottom",
78 | horizontal: "right",
79 | },
80 | preventDuplicate: false,
81 | });
82 | },
83 | });
84 |
85 | const deleteFriendCall=(id)=>{
86 | deletfriend.mutate(id)
87 | }
88 |
89 | return (
90 | <>
91 | {
92 |
93 |
94 | Friends
95 |
96 |
97 |
98 |
99 | {friends &&
100 | friends.map((friend) => (
101 |
102 |
userWindowHandle(friend._id)}
105 | >
106 | {friend.profileUrl ? (
107 |

112 | ) : (
113 |

118 | )}
119 |
120 |
121 | {friend.firstname}{" "}
122 |
123 | {friend.lastname}
124 |
125 |
126 |
127 |
128 | deleteFriendCall(friend._id)} />
129 |
130 |
131 | ))}
132 |
133 |
134 |
135 |
136 | }
137 |
138 |
281 | >
282 | );
283 | };
284 |
285 | export default Friends;
286 |
--------------------------------------------------------------------------------
/one-social-media/src/app/components/homecomponents/Profile/ProfileCard.jsx:
--------------------------------------------------------------------------------
1 | import React, { useState, useContext } from "react";
2 | import { MdOutlineEdit } from "react-icons/md";
3 | import ProfilePhotoUpdate from "./ProfilePhotoUpdate";
4 | import { UserContest } from "@/app/Context/UserContest";
5 | import { adminData } from "@/app/utils/api";
6 | import { useQuery } from "@tanstack/react-query";
7 | import Tooltip from "@mui/material/Tooltip";
8 | import Fade from "@mui/material/Fade";
9 | import Backdrop from "@mui/material/Backdrop";
10 | import CircularProgress from "@mui/material/CircularProgress";
11 |
12 | const ProfileCard = () => {
13 | const [mode, setMode] = useState("");
14 | const context = useContext(UserContest);
15 |
16 | const [profile, profileChange] = useState(false);
17 |
18 | const changeProfile = (e) => {
19 | e.preventDefault();
20 | context.photoUpateType = "PROFILE UPDATE";
21 | setMode("PROFILE UPDATE");
22 | profileChange(true);
23 | };
24 |
25 | const {
26 | data: Admin,
27 | isLoading: loading,
28 | isSuccess: success,
29 | } = useQuery({ queryKey: ["Admin"], queryFn: adminData });
30 | return (
31 | <>
32 |
33 |
34 | Admin
35 |
36 |
37 |
38 | {Admin && Admin?.profileUrl !== null ? (
39 |
45 |
50 |
51 | ) : (
52 |

57 | )}
58 |
59 |
60 |
61 |
62 | {Admin ? (
63 |
64 | @ {Admin?.firstname + "_" + Admin?.lastname}
65 |
66 | ) : (
67 |
68 | @ usernamae
69 |
70 | )}
71 |
72 |
73 |
74 | {Admin && Admin.location !== null ? (
75 |
76 |
{Admin.location}
77 |
78 | ) : (
79 |
82 | )}
83 | {Admin && Admin.profession !== null ? (
84 |
85 |
{Admin.profession}
86 |
87 | ) : (
88 |
91 | )}
92 |
93 |
98 |
99 |
theme.zIndex.drawer + 1 }}
101 | open={loading}
102 | onClick={success}
103 | >
104 |
105 |
106 |
107 | >
108 | );
109 | };
110 |
111 | export default ProfileCard;
112 |
--------------------------------------------------------------------------------
/one-social-media/src/app/components/homecomponents/Profile/ProfilePhotoUpdate.jsx:
--------------------------------------------------------------------------------
1 | import { useContext } from "react";
2 | import { Dialog, DialogContent, DialogTitle, Typography } from "@mui/material";
3 | import React from "react";
4 | import ImageCrop from "../../imagecrop/crop";
5 | import IconButton from "@mui/material/IconButton";
6 | import CloseIcon from "@mui/icons-material/Close";
7 | import { Box } from "@mui/material";
8 | import { UserContest } from "../../../Context/UserContest";
9 | import Stepper from "@mui/material/Stepper";
10 | import Step from "@mui/material/Step";
11 | import StepLabel from "@mui/material/StepLabel";
12 | import { adminData } from "@/app/utils/api";
13 | import { useQuery, useQueryClient } from "@tanstack/react-query";
14 |
15 | const ProfilePhotoUpdate = ({ open, setOpen, mode }) => {
16 | const context = useContext(UserContest);
17 | const queryClient = useQueryClient();
18 | const handleClose = () => {
19 | setOpen(false);
20 | };
21 |
22 | const steps = ["UPLOAD FILE", "UPLOAD"];
23 |
24 | if (context.activeStep === 3) {
25 | handleClose();
26 | }
27 |
28 | const { data: Admin } = useQuery({ queryKey: ["Admin"], queryFn: adminData });
29 |
30 | return (
31 | <>
32 |
33 |
80 |
81 | >
82 | );
83 | };
84 |
85 | export default ProfilePhotoUpdate;
86 |
--------------------------------------------------------------------------------
/one-social-media/src/app/components/homecomponents/Profile/ViewProfile.jsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import {
3 | Dialog,
4 | DialogTitle,
5 | DialogContent,
6 | DialogActions,
7 | Typography,
8 | Divider,
9 | Box,
10 | } from "@mui/material";
11 | import Input from "@/app/components/Input";
12 | import { useQuery } from "@tanstack/react-query";
13 | import { adminData } from "@/app/utils/api";
14 |
15 | const ViewProfile = ({ open, setOpen }) => {
16 | const { data } = useQuery({ queryKey: ["Admin"], queryFn: adminData });
17 | const Admin = data;
18 |
19 | const viewClose = () => {
20 | setOpen(false);
21 | };
22 |
23 | return (
24 |
120 | );
121 | };
122 |
123 | export default ViewProfile;
124 |
--------------------------------------------------------------------------------
/one-social-media/src/app/components/homecomponents/Profile/profileUpdate.jsx:
--------------------------------------------------------------------------------
1 | "use client";
2 | import React, { useState } from "react";
3 | import { adminData, updateUser } from "@/app/utils/api";
4 | import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query";
5 | import CloseIcon from "@mui/icons-material/Close";
6 | import IconButton from "@mui/material/IconButton";
7 | import { AppBar, Toolbar } from "@mui/material";
8 |
9 | const ProfileUpdate = ({ setEdit }) => {
10 | const { data: Admin } = useQuery({ queryKey: ["Admin"], queryFn: adminData });
11 |
12 | const pageData = {
13 | firstname: "",
14 | lastname: "",
15 | DOB: "",
16 | gender: "",
17 | profession: "",
18 | location: "",
19 | };
20 |
21 | const [pagedata, setpage] = useState(pageData);
22 | const queryClient = useQueryClient();
23 |
24 | const onValue = (e) => {
25 | e.preventDefault();
26 | setpage({ ...pagedata, [e.target.name]: e.target.value });
27 | };
28 |
29 | const { mutate } = useMutation({
30 | mutationFn: (pagedata) => updateUser(pagedata),
31 | onSuccess: () => {
32 | setEdit(false);
33 | queryClient.invalidateQueries(["Admin"]);
34 | },
35 | });
36 |
37 | const onpage = (e) => {
38 | mutate(pagedata);
39 | };
40 |
41 | return (
42 |
43 |
44 |
45 |
46 |
47 | Admin Data
48 |
49 |
setEdit(false)}
53 | >
54 |
55 |
56 |
57 |
58 |
59 | {Admin && (
60 |
61 |
Update
62 |
63 | onValue(e)}
70 | />
71 | onValue(e)}
78 | />
79 | onValue(e)}
86 | />
87 | onValue(e)}
94 | />
95 |
96 |
97 |
98 |
Date of birth ?
99 |
onValue(e)}
106 | />
107 |
108 |
109 |
110 |
Gender ?
111 |
121 |
122 |
123 |
{
126 | setEdit(false);
127 | }}
128 | >
129 | cancle
130 |
131 |
132 |
139 |
140 |
141 | )}
142 |
143 | );
144 | };
145 |
146 | export default ProfileUpdate;
147 |
--------------------------------------------------------------------------------
/one-social-media/src/app/components/homecomponents/Suggestion.jsx:
--------------------------------------------------------------------------------
1 | "use client";
2 | import React, { useState } from "react";
3 | import { FaUserPlus } from "react-icons/fa6";
4 | import {
5 | deletePost,
6 | getUser,
7 | getUserPost,
8 | sendFriendRequestMod,
9 | suggestionMode,
10 | } from "@/app/utils/api";
11 | import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query";
12 | import IconButton from "@mui/material/IconButton";
13 | import CloseIcon from "@mui/icons-material/Close";
14 | import DeleteIcon from "@mui/icons-material/Delete";
15 | import FavoriteIcon from "@mui/icons-material/Favorite";
16 | import { Dialog, DialogContent, AppBar, Toolbar } from "@mui/material";
17 | import { useSnackbar } from "notistack";
18 |
19 | const Suggestion = () => {
20 | const queryClient = useQueryClient();
21 | const { data: SuggestionData } = useQuery({
22 | queryKey: ["suggestion"],
23 | queryFn: suggestionMode,
24 | });
25 |
26 | const { enqueueSnackbar } = useSnackbar();
27 |
28 | const RequestMutation = useMutation({
29 | mutationFn: (newData) => sendFriendRequestMod(newData),
30 | onSuccess: (message) => {
31 | queryClient.invalidateQueries({ queryKey: ["suggestion"] });
32 | if (message === "Sent Request") {
33 | enqueueSnackbar(message, {
34 | autoHideDuration: 3000,
35 | variant: "success",
36 | anchorOrigin: {
37 | vertical: "bottom",
38 | horizontal: "right",
39 | },
40 | });
41 | } else {
42 | enqueueSnackbar(message, {
43 | autoHideDuration: 3000,
44 | variant: "error",
45 | anchorOrigin: {
46 | vertical: "bottom",
47 | horizontal: "right",
48 | },
49 | preventDuplicate: false,
50 | });
51 | }
52 | },
53 | });
54 |
55 | const sendRequest = (id) => {
56 | const newData = { requestId: id };
57 | RequestMutation.mutate(newData);
58 | // const newMessage = RequestMutation.data;
59 | // if (newMessage === undefined) {
60 | // enqueueSnackbar("Send Request Success", {
61 | // autoHideDuration: 3000,
62 | // variant: "success",
63 | // anchorOrigin: {
64 | // vertical: "bottom",
65 | // horizontal: "right",
66 | // },
67 | // });
68 | // } else {
69 | // enqueueSnackbar(newMessage, {
70 | // autoHideDuration: 3000,
71 | // variant: "error",
72 | // anchorOrigin: {
73 | // vertical: "bottom",
74 | // horizontal: "right",
75 | // },
76 | // preventDuplicate: false,
77 | // });
78 | // }
79 | };
80 |
81 | //user
82 |
83 | const [userid, setUserId] = useState("");
84 | const [userWindow, setUserWindow] = useState(false);
85 |
86 | const userWindowHandle = (id) => {
87 | setUserId(id);
88 | setUserWindow(true);
89 | mutate();
90 | usePost.mutate();
91 | };
92 |
93 | const handleClose = () => {
94 | setUserWindow(false);
95 | };
96 | const { mutate, data: UserData } = useMutation({
97 | mutationFn: () => getUser(userid),
98 | onSuccess: () => {
99 | queryClient.invalidateQueries({ queryKey: ["user"] });
100 | },
101 | });
102 |
103 | let timestampStr = UserData?.DOB;
104 | let birthday;
105 | if (timestampStr) {
106 | let timestamp = new Date(timestampStr);
107 | birthday = timestamp.toISOString().split("T")[0];
108 | } else {
109 | birthday = null;
110 | }
111 |
112 | //get user
113 | const usePost = useMutation({
114 | mutationFn: () => getUserPost(userid),
115 | onSuccess: () => {
116 | queryClient.invalidateQueries({ queryKey: ["userPost"] });
117 | },
118 | });
119 |
120 | const deletepost = useMutation({
121 | mutationFn: (userid) => deletePost(userid),
122 | onSuccess: () => {
123 | queryClient.invalidateQueries({ queryKey: ["post"] });
124 | setUserWindow(false);
125 | },
126 | });
127 |
128 | const deletePostId = (id) => {
129 | deletepost.mutate(id);
130 | };
131 |
132 | return (
133 |
134 |
135 | Suggestion
136 |
137 |
138 |
139 |
140 | {SuggestionData?.map((friend) => (
141 |
142 |
userWindowHandle(friend._id)}
145 | >
146 | {friend.profileUrl ? (
147 |

152 | ) : (
153 |

158 | )}
159 |
160 | {friend.firstname}{" "}
161 |
162 | {friend.lastname}
163 |
164 |
165 |
166 |
167 |
168 | sendRequest(friend._id)} />
169 |
170 |
171 | ))}
172 |
173 |
174 |
175 |
176 |
319 |
320 | );
321 | };
322 |
323 | export default Suggestion;
324 |
--------------------------------------------------------------------------------
/one-social-media/src/app/components/homecomponents/message.jsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import Link from 'next/link'
3 |
4 | const Message = () => {
5 | return (
6 |
7 |
8 |
14 |
15 |
16 | );
17 | };
18 |
19 | export default Message;
20 |
--------------------------------------------------------------------------------
/one-social-media/src/app/components/imagecrop/canvasPreview.jsx:
--------------------------------------------------------------------------------
1 | const TO_RADIANS = Math.PI / 180;
2 |
3 | export async function canvasPreview(
4 | image,
5 | canvas,
6 | crop,
7 | scale = 1,
8 | rotate = 0
9 | ) {
10 | const ctx = canvas.getContext("2d");
11 |
12 | if (!ctx) {
13 | throw new Error("No 2d context");
14 | }
15 |
16 | const scaleX = image.naturalWidth / image.width;
17 | const scaleY = image.naturalHeight / image.height;
18 | const pixelRatio = window.devicePixelRatio;
19 | canvas.width = Math.floor(crop.width * scaleX * pixelRatio);
20 | canvas.height = Math.floor(crop.height * scaleY * pixelRatio);
21 |
22 | ctx.scale(pixelRatio, pixelRatio);
23 | ctx.imageSmoothingQuality = "high";
24 |
25 | const cropX = crop.x * scaleX;
26 | const cropY = crop.y * scaleY;
27 |
28 | const rotateRads = rotate * TO_RADIANS;
29 | const centerX = image.naturalWidth / 2;
30 | const centerY = image.naturalHeight / 2;
31 | ctx.save();
32 | ctx.translate(-cropX, -cropY);
33 | ctx.translate(centerX, centerY);
34 | ctx.rotate(rotateRads);
35 | ctx.scale(scale, scale);
36 | ctx.translate(-centerX, -centerY);
37 | ctx.drawImage(
38 | image,
39 | 0,
40 | 0,
41 | image.naturalWidth,
42 | image.naturalHeight,
43 | 0,
44 | 0,
45 | image.naturalWidth,
46 | image.naturalHeight
47 | );
48 | ctx.restore();
49 | }
50 |
--------------------------------------------------------------------------------
/one-social-media/src/app/components/imagecrop/crop.jsx:
--------------------------------------------------------------------------------
1 | "use client";
2 | import axios from "axios";
3 | import React, { useState, useRef, useContext } from "react";
4 | import ReactCrop, { centerCrop, makeAspectCrop } from "react-image-crop";
5 | import { canvasPreview } from "./canvasPreview";
6 | import { useDebounceEffect } from "./useDebounceEffect";
7 | import "react-image-crop/dist/ReactCrop.css";
8 | import { UserContest } from "@/app/Context/UserContest";
9 | import { styled } from "@mui/material/styles";
10 | import Button from "@mui/material/Button";
11 | import { Box } from "@mui/material";
12 | import CloudUploadIcon from "@mui/icons-material/CloudUpload";
13 | import Slider from "@mui/material/Slider";
14 | import Backdrop from "@mui/material/Backdrop";
15 | import CircularProgress from "@mui/material/CircularProgress";
16 | import { useSnackbar } from "notistack";
17 | import { useQueryClient,useMutation } from "@tanstack/react-query";
18 | import { makeApost, profileUpdate } from "@/app/utils/api";
19 |
20 | function centerAspectCrop(mediaWidth, mediaHeight, aspect) {
21 | return centerCrop(
22 | makeAspectCrop(
23 | {
24 | unit: "%",
25 | width: 90,
26 | },
27 | aspect,
28 | mediaWidth,
29 | mediaHeight
30 | ),
31 | mediaWidth,
32 | mediaHeight
33 | );
34 | }
35 |
36 | export default function ImageCrop({ mode }) {
37 | const [imgSrc, setImgSrc] = useState("");
38 | const previewCanvasRef = useRef(null);
39 | const imgRef = useRef(null);
40 | const [crop, setCrop] = useState();
41 | const [completedCrop, setCompletedCrop] = useState();
42 | const [scale, setScale] = useState(1);
43 | const [rotate, setRotate] = useState(0);
44 | const [aspect, setAspect] = useState(1 / 1);
45 | const [loading, setLoading] = useState(false);
46 | const [description, setDescription] = useState("");
47 |
48 | const queryClient = useQueryClient();
49 | const context = useContext(UserContest);
50 | const { enqueueSnackbar } = useSnackbar();
51 |
52 | const handleOnChange = (e) => {
53 | setDescription(e.target.value);
54 | };
55 |
56 | const handleSteps = () => {
57 | context.setActiveStep(1);
58 | };
59 |
60 | function onSelectFile(e) {
61 | if (e.target.files && e.target.files.length > 0) {
62 | setCrop(undefined);
63 | const reader = new FileReader();
64 | reader.addEventListener("load", () =>
65 | setImgSrc(reader.result?.toString() || "")
66 | );
67 | reader.readAsDataURL(e.target.files[0]);
68 | context.setActiveStep(1);
69 | }
70 | }
71 |
72 | function onImageLoad(e) {
73 | if (aspect) {
74 | const { width, height } = e.currentTarget;
75 | setCrop(centerAspectCrop(width, height, aspect));
76 | }
77 | }
78 |
79 | const profile = useMutation({
80 | mutationFn:(data)=> profileUpdate(data),
81 | onSuccess: () => {
82 | queryClient.invalidateQueries({ queryKey: ["Admin"] });
83 | context.setActiveStep(3);
84 | enqueueSnackbar("Peofile updated", {
85 | autoHideDuration: 3000,
86 | variant: "success",
87 | anchorOrigin: {
88 | vertical: "bottom",
89 | horizontal: "center",
90 | },
91 | });
92 | },
93 | });
94 |
95 | const post = useMutation({
96 | mutationFn: (data)=> makeApost(description,data),
97 | onSuccess: () => {
98 | queryClient.invalidateQueries({ queryKey: ["post"] });
99 | context.setActiveStep(3);
100 | enqueueSnackbar("Added a new Post", {
101 | autoHideDuration: 3000,
102 | variant: "success",
103 | anchorOrigin: {
104 | vertical: "bottom",
105 | horizontal: "center",
106 | },
107 | });
108 | },
109 | });
110 |
111 | async function onDownloadCropClick() {
112 | handleOpenLoading();
113 | const image = imgRef.current;
114 | const previewCanvas = previewCanvasRef.current;
115 | if (!image || !previewCanvas || !completedCrop) {
116 | throw new Error("Crop canvas does not exist");
117 | }
118 | const scaleX = image.naturalWidth / image.width;
119 | const scaleY = image.naturalHeight / image.height;
120 |
121 | const offscreen = new OffscreenCanvas(
122 | completedCrop.width * scaleX,
123 | completedCrop.height * scaleY
124 | );
125 | const ctx = offscreen.getContext("2d");
126 | if (!ctx) {
127 | throw new Error("No 2d context");
128 | }
129 |
130 | ctx.drawImage(
131 | previewCanvas,
132 | 0,
133 | 0,
134 | previewCanvas.width,
135 | previewCanvas.height,
136 | 0,
137 | 0,
138 | offscreen.width,
139 | offscreen.height
140 | );
141 |
142 | const blob = await offscreen.convertToBlob({
143 | type: "image/png",
144 | });
145 |
146 | const date = Date.now();
147 | const imagename = `photo${date}`;
148 |
149 | const file = new File([blob], imagename, {
150 | type: "image/png",
151 | });
152 |
153 | const formData = new FormData();
154 | formData.append("file", file);
155 | formData.append("upload_preset", "SocilaMedia");
156 | try {
157 | const response = await axios.post(
158 | `https://api.cloudinary.com/v1_1/sociladb/image/upload`,
159 | formData
160 | );
161 | if (response.status == 200) {
162 | const url = response.data.url;
163 | const public_id = response.data.public_id;
164 | const data = { url, public_id };
165 | try {
166 | if (mode !== "MAKE POST") {
167 | profile.mutate(data);
168 | } else {
169 | post.mutate(data);
170 | }
171 | } catch (error) {
172 | enqueueSnackbar(error.message, {
173 | autoHideDuration: 3000,
174 | variant: "error",
175 | anchorOrigin: {
176 | vertical: "bottom",
177 | horizontal: "center",
178 | },
179 | });
180 | }
181 | }
182 | } catch (error) {
183 | enqueueSnackbar(error.response.data.error.message, {
184 | autoHideDuration: 3000,
185 | variant: "error",
186 | anchorOrigin: {
187 | vertical: "bottom",
188 | horizontal: "center",
189 | },
190 | });
191 | }
192 | handleLoading();
193 | }
194 |
195 | useDebounceEffect(
196 | async () => {
197 | if (
198 | completedCrop?.width &&
199 | completedCrop?.height &&
200 | imgRef.current &&
201 | previewCanvasRef.current
202 | ) {
203 | canvasPreview(
204 | imgRef.current,
205 | previewCanvasRef.current,
206 | completedCrop,
207 | scale,
208 | rotate
209 | );
210 | }
211 | },
212 | 100,
213 | [completedCrop, scale, rotate]
214 | );
215 |
216 | const VisuallyHiddenInput = styled("input")({
217 | clip: "rect(0 0 0 0)",
218 | clipPath: "inset(50%)",
219 | height: 1,
220 | overflow: "hidden",
221 | position: "absolute",
222 | bottom: 0,
223 | left: 0,
224 | whiteSpace: "nowrap",
225 | width: 1,
226 | });
227 |
228 | //loading
229 | const handleLoading = () => {
230 | setLoading(false);
231 | };
232 | const handleOpenLoading = () => {
233 | setLoading(true);
234 | };
235 |
236 | return (
237 |
238 | {mode === "MAKE POST" && (
239 |
240 |
249 |
250 | )}
251 |
252 |
253 |
254 |
}
259 | >
260 |
Upload file
261 |
262 |
263 |
264 |
265 | {!!imgSrc && (
266 |
267 |
setCrop(percentCrop)}
270 | onComplete={(c) => setCompletedCrop(c)}
271 | aspect={aspect}
272 | minHeight={100}
273 | className="outline outline-2 outline-offset-2"
274 | >
275 |
283 |
284 |
285 | )}
286 |
287 | {!!completedCrop && (
288 |
289 |
290 |
294 |
295 | {/* new */}
296 |
297 |
298 | setScale(Number(e.target.value))}
309 | />
310 |
311 |
312 |
313 |
314 |
315 |
328 | setRotate(
329 | Math.min(180, Math.max(-180, Number(e.target.value)))
330 | )
331 | }
332 | />
333 |
334 |
335 |
336 |
343 |
344 |
345 | )}
346 |
347 |
348 |
theme.zIndex.drawer + 1 }}
350 | open={loading}
351 | onClick={handleLoading}
352 | >
353 |
354 |
355 |
356 |
357 | );
358 | }
359 |
--------------------------------------------------------------------------------
/one-social-media/src/app/components/imagecrop/useDebounceEffect.jsx:
--------------------------------------------------------------------------------
1 | import { useEffect, DependencyList } from "react";
2 |
3 | export function useDebounceEffect(fn, waitTime, deps) {
4 | useEffect(() => {
5 | const t = setTimeout(() => {
6 | fn.apply(deps);
7 | }, waitTime);
8 |
9 | return () => {
10 | clearTimeout(t);
11 | };
12 | }, deps);
13 | }
14 |
--------------------------------------------------------------------------------
/one-social-media/src/app/components/login/Main.jsx:
--------------------------------------------------------------------------------
1 | "use client";
2 | import { useState } from "react";
3 | import {
4 | Dialog,
5 | DialogTitle,
6 | DialogContent,
7 | DialogActions,
8 | Typography,
9 | Divider,
10 | Box,
11 | } from "@mui/material";
12 | import axios from "axios";
13 | import Backdrop from "@mui/material/Backdrop";
14 | import CircularProgress from "@mui/material/CircularProgress";
15 | import { useSnackbar } from "notistack";
16 |
17 | const Home = () => {
18 | const APP_URL = process.env.NEXT_PUBLIC_BACKEND;
19 | const { enqueueSnackbar } = useSnackbar();
20 | const loginData = { email: "", password: "" };
21 | const registerData = {
22 | firstname: "",
23 | lastname: "",
24 | email: "",
25 | password: "",
26 | DOB: "",
27 | gender: "",
28 | };
29 |
30 | const [logindata, setloginData] = useState(loginData);
31 | const [registerdata, setRegister] = useState(registerData);
32 | const [loading, setLoading] = useState(false);
33 | const [open, setOpen] = useState(false);
34 | const [passwordResetRequest, setPasswordResetRequest] = useState(false);
35 | const [resetEmail, setResetEmail] = useState("");
36 |
37 | const onValueChange = (e) => {
38 | e.preventDefault();
39 | setloginData({ ...logindata, [e.target.name]: e.target.value });
40 | };
41 |
42 | const onValue = (e) => {
43 | e.preventDefault();
44 | setRegister({ ...registerdata, [e.target.name]: e.target.value });
45 | };
46 |
47 | const onRegister = async () => {
48 | handleOpenLoading();
49 | try {
50 | const result = await axios.post(APP_URL + "/register", registerdata);
51 | if (result?.message === "Authentication failed") {
52 | localStorage.removeItem("user");
53 | window.alert("user session expair Login again. ");
54 | window.location.replace("/");
55 | }
56 | if (result.status === 200) {
57 | setRegister(registerData);
58 | enqueueSnackbar(result.data.message, {
59 | autoHideDuration: 2000,
60 | variant: "success",
61 | anchorOrigin: {
62 | vertical: "bottom",
63 | horizontal: "right",
64 | },
65 | preventDuplicate: false,
66 | });
67 | } else {
68 | enqueueSnackbar(result.data.message, {
69 | autoHideDuration: 2000,
70 | variant: "error",
71 | anchorOrigin: {
72 | vertical: "bottom",
73 | horizontal: "right",
74 | },
75 | preventDuplicate: false,
76 | });
77 | }
78 |
79 | handleLoading();
80 | setOpen(false);
81 | } catch (error) {
82 | handleLoading();
83 | enqueueSnackbar(result.data.message, {
84 | autoHideDuration: 2000,
85 | variant: "error",
86 | anchorOrigin: {
87 | vertical: "bottom",
88 | horizontal: "right",
89 | },
90 | preventDuplicate: false,
91 | });
92 | }
93 | };
94 |
95 | const onLogin = async () => {
96 | handleOpenLoading();
97 | try {
98 | const result = await axios.post(APP_URL + "/login", logindata,{
99 | withCredentials:true
100 | });
101 | if (result.status === 200) {
102 | localStorage.setItem("user", result.data.data);
103 | setloginData(loginData);
104 | window.location.replace("/home");
105 | handleLoading();
106 | } else {
107 | handleLoading();
108 | enqueueSnackbar(result.data.message, {
109 | autoHideDuration: 2000,
110 | variant: "error",
111 | anchorOrigin: {
112 | vertical: "bottom",
113 | horizontal: "right",
114 | },
115 | preventDuplicate: false,
116 | });
117 | }
118 | } catch (error) {
119 | handleLoading();
120 | }
121 | };
122 |
123 | const dummyLogin = async (e) => {
124 | handleOpenLoading();
125 | const data = {
126 | email: "test@gmail.com",
127 | password: "password",
128 | };
129 | try {
130 | const result = await axios.post(APP_URL + "/login", data, {
131 | withCredentials: true,
132 | });
133 |
134 | if (result.status === 200) {
135 | localStorage.setItem("user", result.data.data);
136 | window.location.replace("/home");
137 | handleLoading();
138 | } else {
139 | handleClick();
140 | handleLoading();
141 | }
142 | } catch (error) {
143 | handleLoading();
144 | }
145 | };
146 |
147 | const passwordRequest = async () => {
148 | handleOpenLoading();
149 | if (resetEmail) {
150 | const response = await axios.post(
151 | APP_URL + "/user/password-reset-request",
152 | { email: resetEmail }
153 | );
154 | if (response.status === 200) {
155 | onHadlepasswordResetRequestClose();
156 | enqueueSnackbar(response.data.message, {
157 | autoHideDuration: 2000,
158 | variant: "success",
159 | anchorOrigin: {
160 | vertical: "bottom",
161 | horizontal: "right",
162 | },
163 | preventDuplicate: false,
164 | });
165 | } else {
166 | enqueueSnackbar(response.data.message, {
167 | autoHideDuration: 2000,
168 | variant: "error",
169 | anchorOrigin: {
170 | vertical: "bottom",
171 | horizontal: "right",
172 | },
173 | preventDuplicate: false,
174 | });
175 | }
176 | handleLoading();
177 | }
178 | };
179 |
180 | const handleClose = () => {
181 | setOpen(false);
182 | };
183 | const handleOpen = (e) => {
184 | e.preventDefault();
185 | setOpen(true);
186 | };
187 |
188 | const handleLoading = () => {
189 | setLoading(false);
190 | };
191 |
192 | const handleOpenLoading = () => {
193 | setLoading(true);
194 | };
195 |
196 | const onHadlepasswordResetRequest = () => {
197 | setPasswordResetRequest(true);
198 | };
199 |
200 | const onHadlepasswordResetRequestClose = () => {
201 | setPasswordResetRequest(false);
202 | };
203 |
204 | return (
205 |
206 |
207 |
208 |
{
212 | if (event.key === "Enter") onLogin();
213 | }}
214 | value={logindata.email}
215 | placeholder="Email Address"
216 | className="w-full border p-2 border-gray-400 text-white bg-black rounded-md focus:outline-none focus:ring-1 ring-white my-2"
217 | onChange={(e) => onValueChange(e)}
218 | />
219 |
{
223 | if (event.key === "Enter") onLogin();
224 | }}
225 | value={logindata.password}
226 | placeholder="Password"
227 | className="w-full border p-2 border-gray-400 text-white bg-black rounded-md focus:outline-none focus:border-white my-2"
228 | onChange={(e) => onValueChange(e)}
229 | />
230 |
231 |
238 |
239 |
246 |
247 |
254 |
255 |
256 |
263 |
264 |
265 |
266 |
267 |
268 | {" "}
269 | Create a Page for a celebrity,
270 | brand or business.
271 |
272 |
273 |
274 |
369 |
370 |
421 |
theme.zIndex.drawer + 1 }}
423 | open={loading}
424 | onClick={handleLoading}
425 | >
426 |
427 |
428 |
429 | );
430 | };
431 |
432 | export default Home;
433 |
--------------------------------------------------------------------------------
/one-social-media/src/app/components/useDebounceEffect.jsx:
--------------------------------------------------------------------------------
1 | import { useEffect } from "react";
2 |
3 | export function useDebounceEffect(fn, waitTime, deps) {
4 | useEffect(() => {
5 | const timer = setTimeout(() => {
6 | fn.apply(undefined, deps);
7 | }, waitTime);
8 | return () => {
9 | clearTimeout(timer);
10 | };
11 | }, deps);
12 | }
13 |
--------------------------------------------------------------------------------
/one-social-media/src/app/data/Data.js:
--------------------------------------------------------------------------------
1 | export const footerLinks = [
2 | {
3 | title: "About",
4 | links: [
5 | { title: "About Us", url: "https://hareeshdhruva.vercel.app/" },
6 | ],
7 | },
8 | {
9 | title: "Socials",
10 | links: [
11 | { title: "Linkedin", url: "https://www.linkedin.com/in/hareesh-dhruva-797240296" },
12 | { title: "Git hub", url: "https://github.com/HareeshDhruva" },
13 | ],
14 | },
15 | ];
16 |
--------------------------------------------------------------------------------
/one-social-media/src/app/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HareeshDhruva/osm/a227fa46f76bf4cdac4e7f6f622b48c9417c3511/one-social-media/src/app/favicon.ico
--------------------------------------------------------------------------------
/one-social-media/src/app/globals.css:
--------------------------------------------------------------------------------
1 | @import url("https://fonts.googleapis.com/css2?family=Poppins&display=swap");
2 | @tailwind base;
3 | @tailwind components;
4 | @tailwind utilities;
5 |
6 | ::-webkit-scrollbar {
7 | width: 1px;
8 | visibility: hidden;
9 | }
10 |
11 | ::-webkit-scrollbar {
12 | display: block;
13 | }
14 |
15 | ::-webkit-scrollbar-thumb {
16 | border-radius: 20%;
17 | visibility: hidden;
18 | }
19 |
20 | body {
21 | font-size: 16px;
22 | background-color: black;
23 | font-family: "Poppins", sans-serif;
24 | }
25 |
26 | html {
27 | font-family: "Poppins", sans-serif;
28 | }
29 |
30 | @media only screen and (max-width: 600px) {
31 | body {
32 | font-size: 12px;
33 | }
34 | }
35 |
36 | @media only screen and (min-width: 601px) and (max-width: 900px) {
37 | body {
38 | font-size: 14px;
39 | }
40 | }
41 |
42 | @media only screen and (min-width: 901px) {
43 | body {
44 | font-size: 15px;
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/one-social-media/src/app/home/page.jsx:
--------------------------------------------------------------------------------
1 | "use client";
2 | import ProfileCard from "../components/homecomponents/Profile/ProfileCard";
3 | import NavBar from "../components/NavBar";
4 | import Footer from "../components/Footer";
5 | import Post from "../components/Post/Post";
6 | import FriendRequest from "../components/homecomponents/FriendRequest";
7 | import Suggestion from "../components/homecomponents/Suggestion";
8 | import Friends from "../components/homecomponents/Friends";
9 | import { useQuery } from "@tanstack/react-query";
10 | import { adminData } from "../utils/api";
11 | import Backdrop from "@mui/material/Backdrop";
12 | import CircularProgress from "@mui/material/CircularProgress";
13 |
14 | const Home = () => {
15 | const {
16 | data: Admin,
17 | isLoading: loading,
18 | isSuccess: success,
19 | } = useQuery({ queryKey: ["Admin"], queryFn: adminData });
20 | return (
21 |
22 | {Admin && (
23 | <>
24 |
25 |
26 |
27 |
31 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
theme.zIndex.drawer + 1 }}
42 | open={loading}
43 | onClick={success}
44 | >
45 |
46 |
47 | >
48 | )}
49 |
50 | );
51 | };
52 |
53 | export default Home;
54 |
--------------------------------------------------------------------------------
/one-social-media/src/app/layout.js:
--------------------------------------------------------------------------------
1 | import "./globals.css";
2 | import { Inter } from "next/font/google";
3 | const inter = Inter({ subsets: ["latin"] });
4 | import PhotoContestProvider from "./Context/UserContest";
5 | import QueryProvider from "./QueryProvider";
6 |
7 | export const metadata = {
8 | title: "one social media",
9 | description:
10 | "Connecting people, one post at a time. Welcome to one social media platform for sharing moments, connecting with friends, and discovering what matters to you. Join the community today and make every day memorable. #ConnectShareDiscover #SocialMediaRevolution #oms #one-social-media #oneSocialMedia #onesocialmedia #1socialmedia",
11 | };
12 |
13 | export default function RootLayout({ children }) {
14 | return (
15 |
16 |
17 |
18 | {children}
19 |
20 |
21 |
22 | );
23 | }
24 |
--------------------------------------------------------------------------------
/one-social-media/src/app/page.js:
--------------------------------------------------------------------------------
1 | import Register from "@/app/components/login/Main";
2 | import Leftpart from "./components/LogoPart";
3 |
4 | export default function Home() {
5 | return (
6 | <>
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 | >
18 | );
19 | }
20 |
--------------------------------------------------------------------------------
/one-social-media/src/app/utils/api.js:
--------------------------------------------------------------------------------
1 | import axios from "axios";
2 | const URL = process.env.NEXT_PUBLIC_BACKEND;
3 | const token = typeof window !== "undefined" ? localStorage.getItem("user") : null;
4 |
5 | export const adminData = async () => {
6 | const res = await axios.post(`${URL}/getuser`, {
7 | headers: {
8 | "Content-Type": "application/json",
9 | authorization: token ? `Bearer ${token}` : "",
10 | },
11 | });
12 | return res.data.data;
13 | };
14 |
15 | export const getUser = async (id) => {
16 | const res = await axios.post(`${URL}/getuser/${id}`, {
17 | headers: {
18 | "Content-Type": "application/json",
19 | authorization: token ? `Bearer ${token}` : "",
20 | },
21 | });
22 | if (res.status === 200) {
23 | return res.data.data;
24 | }
25 | };
26 |
27 | export const suggestionMode = async () => {
28 | const res = await axios.post(`${URL}/suggested`, {
29 | headers: {
30 | "Content-Type": "application/json",
31 | authorization: token ? `Bearer ${token}` : "",
32 | },
33 | });
34 | if (res.status === 200) {
35 | return res.data.data;
36 | }
37 | };
38 |
39 | export const friendRequestMode = async () => {
40 | const res = await axios.post(`${URL}/getFriendRequest`, {
41 | headers: {
42 | "Content-Type": "application/json",
43 | authorization: token ? `Bearer ${token}` : "",
44 | },
45 | });
46 | return res.data.data;
47 | };
48 |
49 | export const friendRequestAcceptMode = async (data) => {
50 | const res = await axios.post(`${URL}/acceptFriendRequest`, {
51 | data: data,
52 | headers: {
53 | "Content-Type": "application/json",
54 | authorization: token ? `Bearer ${token}` : "",
55 | },
56 | });
57 | if (res.status === 200) {
58 | return res.data.message;
59 | }
60 | };
61 |
62 | export const updateProfilePhoto = (data) => {
63 | return async (dispatch) => {
64 | await axios.post(`${URL}/updateProfilePhoto`, {
65 | data: data,
66 | headers: {
67 | "Content-Type": "application/json",
68 | authorization: token ? `Bearer ${token}` : "",
69 | },
70 | });
71 | };
72 | };
73 |
74 | export const sendFriendRequestMod = async (requestId) => {
75 | const res = await axios.post(`${URL}/sendFriendRequest`, {
76 | data: requestId,
77 | headers: {
78 | "Content-Type": "application/json",
79 | authorization: token ? `Bearer ${token}` : "",
80 | },
81 | });
82 | return res.data.message;
83 | };
84 |
85 | export const getAllPost = async () => {
86 | const res = await axios.get(`${URL}`);
87 | return res.data.data;
88 | };
89 |
90 | export const likeAPost = (id) => {
91 | return async (dispatch) => {
92 | await axios
93 | .post(`${URL}/like/${id}`, {
94 | headers: {
95 | "Content-Type": "application/json",
96 | authorization: token ? `Bearer ${token}` : "",
97 | },
98 | })
99 | .then((response) => {
100 | if (response.status === 200) {
101 | console.log("success");
102 | }
103 | })
104 | .catch((error) => {
105 | console.log(error.message);
106 | });
107 | };
108 | };
109 |
110 | export const getComment = async (id) => {
111 | const res = await axios.get(`${URL}/comment/${id}`, {
112 | headers: {
113 | "Content-Type": "application/json",
114 | authorization: token ? `Bearer ${token}` : "",
115 | },
116 | });
117 | return res.data.data;
118 | };
119 |
120 | export const makeAComment = async (data, id) => {
121 | if (data) {
122 | return await axios.post(`${URL}/comment-post/${id}`, {
123 | comment: data,
124 | headers: {
125 | "Content-Type": "application/json",
126 | authorization: token ? `Bearer ${token}` : "",
127 | },
128 | });
129 | }
130 | };
131 |
132 | export const replyCommentMod = async (comment, from, url, id) => {
133 | if (comment) {
134 | const data = { comment, from, url };
135 | return await axios.post(`${URL}/reply-comment/${id}`, {
136 | data: data,
137 | headers: {
138 | "Content-Type": "application/json",
139 | authorization: token ? `Bearer ${token}` : "",
140 | },
141 | });
142 | }
143 | };
144 |
145 | export const getUserPost = async (id) => {
146 | const res = await axios.post(`${URL}/get-user-post/${id}`, {
147 | headers: {
148 | "Content-Type": "application/json",
149 | authorization: token ? `Bearer ${token}` : "",
150 | },
151 | });
152 | if (res.status == 200) {
153 | return res.data.data;
154 | }
155 | };
156 |
157 |
158 | export const updateUser = async (pagedata) => {
159 | const response = await axios.post(`${URL}/updateUser`, {
160 | data: pagedata,
161 | headers: {
162 | "Content-Type": "application/json",
163 | authorization: token ? `Bearer ${token}` : "",
164 | },
165 | });
166 | return response.data.data;
167 | };
168 |
169 | export const likeAcomment = async (data) => {
170 | const { id, rid } = data;
171 | return await axios.post(`${URL}/like-comment/${id}/${rid}`, {
172 | headers: {
173 | "Content-Type": "application/json",
174 | authorization: token ? `Bearer ${token}` : "",
175 | },
176 | });
177 | };
178 |
179 | export const deletePost = async (id) => {
180 | const res = await axios.post(`${URL}/delete-post/${id}`, {
181 | headers: {
182 | "Content-Type": "application/json",
183 | authorization: token ? `Bearer ${token}` : "",
184 | },
185 | });
186 | return res.data.message;
187 | };
188 |
189 | export const deleteFriend = async (data) => {
190 | const res = await axios.post(`${URL}/deleteFriend`, {
191 | data: data,
192 | headers: {
193 | "Content-Type": "application/json",
194 | authorization: token ? `Bearer ${token}` : "",
195 | },
196 | });
197 | return res.data.message;
198 | };
199 |
200 | export const profileUpdate = async(file)=>{
201 | console.log(file)
202 | return await axios.post(`${URL}/updateProfilePhoto`, {
203 | method: "POST",
204 | data:file,
205 | headers: {
206 | "Content-Type": "application/json",
207 | authorization: token ? `Bearer ${token}` : "",
208 | },
209 | });
210 | }
211 |
212 | export const makeApost = async (description, image) => {
213 | const data = { description, image };
214 | return await axios.post(`${URL}/create-post`, {
215 | data: data,
216 | headers: {
217 | "Content-Type": "application/json",
218 | authorization: token ? `Bearer ${token}` : "",
219 | },
220 | });
221 | };
--------------------------------------------------------------------------------
/one-social-media/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 | extend: {
10 | backgroundImage: {
11 | "gradient-radial": "radial-gradient(var(--tw-gradient-stops))",
12 | "gradient-conic":
13 | "conic-gradient(from 180deg at 50% 50%, var(--tw-gradient-stops))",
14 | },
15 | },
16 | },
17 | plugins: [],
18 | };
19 |
--------------------------------------------------------------------------------
/server/.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 | # production
12 | /build
13 |
14 | # misc
15 | .DS_Store
16 | *.pem
17 |
18 | # debug
19 | npm-debug.log*
20 | yarn-debug.log*
21 | yarn-error.log*
22 |
23 | # local env files
24 | .env*.local
25 | .env
26 |
27 | # vercel
28 | .vercel
29 |
30 | # typescript
31 | *.tsbuildinfo
32 | next-env.d.ts
33 |
--------------------------------------------------------------------------------
/server/config.js:
--------------------------------------------------------------------------------
1 | const mongoose = require("mongoose");
2 |
3 | const connection = async (URL) => {
4 | try {
5 | const connected = await mongoose.connect(URL);
6 | if (connected) {
7 | console.log("Dastabase connected Sucessfullly");
8 | } else {
9 | console.log("DB connected fail");
10 | }
11 | } catch (error) {
12 | console.log(error);
13 | }
14 | };
15 | module.exports = connection;
16 |
--------------------------------------------------------------------------------
/server/controllers/authController.js:
--------------------------------------------------------------------------------
1 | const User = require("../models/userModels");
2 | const { hasing, createJWT ,comparePassword} = require("../utils");
3 | const {sendNotififcation} = require('../utils/sendVerification')
4 | const bcrypt = require('bcrypt');
5 | const { sendPasswordchangeEmail } = require("../utils/passwordChange");
6 | const {sendPasswordReset} = require('../utils/passwordResetRequest');
7 | const jwt = require("jsonwebtoken");
8 |
9 | const register = async(req,res) =>{
10 | const {firstname,lastname,email,password,DOB,gender} = req.body;
11 | if(!firstname || !lastname || !email || !password){
12 | return res.status(201).json({message:"Provide all Fields"});
13 | }
14 | try{
15 | const ExistUser = await User.findOne({email});
16 | if(ExistUser){
17 | return res.status(201).json({message:"Email Already Exist"});
18 | }
19 |
20 | const hasedPassword = await hasing(password);
21 | const user = await User.create({
22 | firstname,
23 | lastname,
24 | email:email.toLowerCase(),
25 | DOB,
26 | gender,
27 | password:hasedPassword,
28 | })
29 | sendNotififcation(user,res)
30 | user.save();
31 | }
32 | catch(err){
33 | res.status(201).json({message:err.message});
34 | }
35 | }
36 |
37 |
38 | const login = async(req,res) => {
39 | const {email,password} = req.body;
40 | try{
41 | if(!email || !password){
42 | return res.status(201).json({message:"Enter Email And Password"})
43 | }
44 | const user = await User.findOne({email});
45 | if(!user){
46 | return res.status(201).json({message:"User Not Exist"})
47 | }
48 | const validPass = bcrypt.compare(password, user.password)
49 |
50 | if(!validPass){
51 | return res.status(201).json({message:"Incorrect Password"})
52 | }
53 | if(user.verified === true){
54 | const token = createJWT(user._id)
55 | res.cookie('token', token, {
56 | path: "/",
57 | maxAge: 90000,
58 | sameSite: 'None',
59 | secure: true,
60 | Domain:"osm-beta.vercel.app"
61 | });
62 | return res.status(200).json({ data:token});
63 | }
64 | else{
65 | res.status(201).json({message:"Please Verify The Email"});
66 | }
67 | }
68 | catch(error){
69 | return res.status(201).json({message:error});
70 | }
71 | }
72 |
73 | const resetPasswordRequest = async(req,res) => {
74 | try{
75 | const {email} = req.body;
76 | const user = await User.findOne({email});
77 | if(!user){
78 | return res.status(201).json({message:"Email Not Found"})
79 | }
80 | sendPasswordReset(user,res);
81 | }
82 | catch(error){
83 | res.status(201).json({message:"User Not Found"})
84 | }
85 | }
86 |
87 | const passwordChange = async (req,res) => {
88 | const token = req.cookies.token;
89 | if(!token){
90 | return res.status(201).json({message:'User Not Login'});
91 | }
92 | const payload = jwt.decode(token);
93 | const {password,newPassword} = req.body;
94 | const user = await User.findOne({_id:payload.userId});
95 | if(!user){
96 | return res.status(201).json({message:"This Email Not Found"})
97 | }
98 | const result = await comparePassword(password,user.password);
99 |
100 | if(result){
101 | const hasedPassword = await hasing(newPassword);
102 | const newuser = await User.findOneAndUpdate({_id:payload.userId},{password:hasedPassword})
103 | sendPasswordchangeEmail(newuser,res);
104 | console.log("Password Change Sucess");
105 | }
106 | else{
107 | res.status(201).json({message:"Incorrect Previos Password"})
108 | }
109 | }
110 |
111 | const verifiedpasswordChange = async(req,res) => {
112 | try{
113 | const hasedPassword = await hasing(req.body.newPassword);
114 | const newuser = await User.findOneAndUpdate({_id:req.body.userId},{password:hasedPassword})
115 | sendPasswordchangeEmail(newuser,res);
116 | }
117 | catch(error){
118 | res.status(201).json({message:"fail"});
119 | }
120 | }
121 |
122 | const logout = (req,res)=>{
123 | const token = "";
124 | res.status(200).cookie("token",token,{httpOnly:true,expaisIn:"1D", path: "/"}).json({message:"logout"});
125 | }
126 |
127 |
128 | module.exports = {register,login,logout,resetPasswordRequest,passwordChange,verifiedpasswordChange}
129 |
130 |
--------------------------------------------------------------------------------
/server/controllers/comments.js:
--------------------------------------------------------------------------------
1 | const Comment = require("../models/commentModel");
2 | const Post = require("../models/postModel");
3 |
4 | const getComments = async (req, res) => {
5 | try {
6 | const { postId } = req.params;
7 | const postComment = await Comment.find({ postId })
8 | .populate({
9 | path: "userId postId",
10 | select: "-password",
11 | })
12 | .populate({
13 | path: "replies.userId",
14 | select: "-password",
15 | })
16 | .sort({ _id: -1 });
17 | res.status(200).json({
18 | success: true,
19 | message: "success",
20 | data: postComment,
21 | });
22 | } catch (error) {
23 | res.status(201).json({ message: "fail" });
24 | }
25 | };
26 |
27 | const likeApost = async (req, res) => {
28 | try {
29 | const { userId } = req.body.user;
30 | const { id } = req.params;
31 | const post = await Post.findById({ _id: id });
32 | if (post.likes.includes(String(userId))) {
33 | post.likes = post.likes.filter((pid) => pid !== String(userId));
34 | } else {
35 | post.likes.push(userId);
36 | }
37 | const newPost = await Post.findByIdAndUpdate(id, post);
38 |
39 | res.status(200).json({
40 | success: true,
41 | message: "successfully",
42 | data: newPost,
43 | });
44 | } catch (error) {
45 | res.status(201).json({ message: "something went wrong" });
46 | }
47 | };
48 |
49 | const likeAcomment = async (req, res) => {
50 | const { userId } = req.body.user;
51 | const { id, rid } = req.params;
52 | try {
53 | if (rid === undefined || rid === null || rid === "false") {
54 | const comment = await Comment.findById(id);
55 | const index = comment.likes.findIndex((el) => el === String(userId));
56 | if (index === -1) {
57 | comment.likes.push(userId);
58 | } else {
59 | comment.likes = comment.likes.filter((i) => i === String(userId));
60 | }
61 |
62 | const updated = await Comment.findByIdAndUpdate(id, comment, {
63 | new: true,
64 | });
65 | res.status(200).json({
66 | success: true,
67 | message: "Successfully",
68 | data: updated,
69 | });
70 | } else {
71 | const replyComment = await Comment.findOne(
72 | { _id: id },
73 | {
74 | replies: {
75 | $elemMatch: {
76 | _id: rid,
77 | },
78 | },
79 | }
80 | );
81 | const index = replyComment?.replies[0]?.likes.findIndex(
82 | (i) => i === String(userId)
83 | );
84 | if (index === -1) {
85 | replyComment.replies[0].likes.push(userId);
86 | } else {
87 | replyComment.replies[0].likes = replyComment.replies[0]?.likes.filter(
88 | (i) => i !== String(userId)
89 | );
90 | }
91 | const query = { _id: id, "replies._id": rid };
92 | const update = {
93 | $set: {
94 | "replies.$.likes": replyComment.replies[0].likes,
95 | },
96 | };
97 | const result = await Comment.findOneAndUpdate(query, update, {
98 | new: true,
99 | });
100 | res.status(200).json(result);
101 | }
102 | } catch (error) {
103 | res.status(201).json({ message: "something went wrong" });
104 | }
105 | };
106 |
107 | const commentPost = async (req, res) => {
108 | try {
109 | const { comment, from } = req.body;
110 | const { userId } = req.body.user;
111 | const { id } = req.params;
112 | if (comment === null) {
113 | res.status(404).json({ message: "comment is required" });
114 | }
115 | const newComment = new Comment({ comment, from, userId, postId: id });
116 | await newComment.save();
117 | const post = await Post.findById(id);
118 | post.comments.push(newComment._id);
119 | const UpdatePost = await Post.findByIdAndUpdate(id, post, { new: true });
120 | res.status(200).json({
121 | success: true,
122 | message: "Successfully",
123 | data: UpdatePost,
124 | });
125 | } catch (error) {
126 | res.status(201).json("something went wrong");
127 | }
128 | };
129 |
130 | const replyPostComment = async (req, res, next) => {
131 | const { userId } = req.body.user;
132 | const { comment, from, url } = req.body.data;
133 | const { id } = req.params;
134 | if (comment === null) {
135 | return res.status(201).json({ message: "Comment is Requires" });
136 | }
137 | try {
138 | const commentInfo = await Comment.findById(id);
139 | commentInfo.replies.push({
140 | comment,
141 | from,
142 | url,
143 | userId,
144 | created_At: Date.now(),
145 | });
146 | commentInfo.save();
147 | res.status(200).json({ data: commentInfo });
148 | } catch (error) {
149 | res.status(201).json({ message: "somthing went wrong" });
150 | return;
151 | }
152 | };
153 |
154 | module.exports = {
155 | getComments,
156 | likeApost,
157 | likeAcomment,
158 | commentPost,
159 | replyPostComment,
160 | };
161 |
--------------------------------------------------------------------------------
/server/controllers/passwordReset.js:
--------------------------------------------------------------------------------
1 | const PasswordReset = require("../models/passwordResetSchema");
2 | const User = require("../models/userModels");
3 | const { decodePassword } = require("../utils/index");
4 |
5 | const passworsReset = async (req, res) => {
6 | const { userId } = req.params;
7 | try {
8 | const result = await PasswordReset.findOne({ userId });
9 | const { expires_At } = result;
10 | if (result) {
11 | if (expires_At < Date.now()) {
12 | await PasswordReset.findOneAndDelete({ userId })
13 | .then(() => {
14 | User.findOne({ _id: userId })
15 | .then(() => {
16 | const message = "Reset token has expaired";
17 | res.redirect(
18 | `/user/password-reset?status=error&message=${message}`
19 | );
20 | })
21 | .catch((error) => {
22 | res.redirect(`/user/password-reset?message=${error}`);
23 | });
24 | })
25 | .catch((error) => {
26 | res.redirect(`/user/password-reset?message=${error}`);
27 | });
28 | } else {
29 | decodePassword(userId, result.token)
30 | .then(async (isMatch) => {
31 | if (isMatch) {
32 | await User.findOne({ _id: userId })
33 | .then((user) => {
34 | if(user){
35 | res.redirect(`/user/password-reset?_id=${userId}`);
36 | }
37 | })
38 | .catch((error) => {
39 | res.redirect(`/user/password-reset?status=fail`);
40 | });
41 | } else {
42 | res.redirect(
43 | `/user/password-reset?status=succes&message=${isMatch}`
44 | );
45 | }
46 | })
47 | .catch((error) => {
48 | res.redirect(`/user/password-reset?message=${error}`);
49 | });
50 | }
51 | }
52 | } catch (error) {
53 | res.status(201).json({ message: "user not exist" });
54 | }
55 | };
56 |
57 | module.exports = passworsReset;
58 |
--------------------------------------------------------------------------------
/server/controllers/post.js:
--------------------------------------------------------------------------------
1 | require('dotenv').config();
2 | const Post = require("../models/postModel");
3 | const cloudinary = require('cloudinary');
4 |
5 | const createPost = async (req, res) => {
6 | try {
7 | const { userId } = req.body.user;
8 | const { description, image } = req.body.data;
9 | if (!image) {
10 | return res.status(201).json("image must!");
11 | }
12 | const post = await Post.create({
13 | userId,
14 | description,
15 | image,
16 | });
17 | res.status(200).json({ data: post });
18 | } catch (error) {
19 | res.status(201).json({ message: "failed in post" });
20 | }
21 | };
22 |
23 | const getPost = async (req, res) => {
24 | try {
25 | const posts = await Post.find()
26 | .populate({
27 | path: 'userId',
28 | select: '-password',
29 | })
30 | .populate({
31 | path: 'comments',
32 | populate: {
33 | path: 'userId',
34 | select: '-password',
35 | },
36 | })
37 | .sort({ _id: -1 });
38 | res.status(200).json({
39 | data: posts,
40 | success: true,
41 | message: "successfuuly",
42 | });
43 | } catch (error) {
44 | res.status(201).json({ message: "something went wrong" });
45 | }
46 | };
47 |
48 | const getuserPost = async (req, res) => {
49 | try {
50 | const { id } = req.params;
51 | const userpost = await Post.find({ userId: id })
52 | .populate({
53 | path: "userId",
54 | select: "-password",
55 | })
56 | .sort({ _id: -1 });
57 |
58 | res.status(200).json({
59 | message: "successfully",
60 | success: true,
61 | data: userpost,
62 | });
63 | } catch (error) {
64 | res.status(201).json({ message: "Post not yet !" });
65 | }
66 | };
67 |
68 | const deletePost = async (req, res) => {
69 | const { id } = req.params;
70 | const { userId } = req.body.user;
71 |
72 | try {
73 | const postfound = await Post.findById({ _id: id });
74 | if (postfound) {
75 | if (postfound.userId.toString() === userId) {
76 | const result = await Post.findByIdAndDelete({ _id: id });
77 | if (result) {
78 | cloudinary.v2.api.delete_resources(postfound.image.public_id).then(()=>{
79 | return res.status(200).json({ message: "Delete Success"});
80 | });
81 | }
82 | } else {
83 | res.status(201).json({ message: `Only admin can delete` });
84 | }
85 | } else {
86 | res.status(201).json({ message: "Post already deleted" });
87 | }
88 | } catch (error) {
89 | res.status(201).json({ message: "Somthing went wrong" });
90 | }
91 | };
92 |
93 | module.exports = { createPost, getuserPost, deletePost, getPost };
94 |
--------------------------------------------------------------------------------
/server/controllers/userControl.js:
--------------------------------------------------------------------------------
1 | const mongoose = require("mongoose");
2 | const Verification = require("../models/emailVerificatin");
3 | const User = require("../models/userModels");
4 | const { decodePassword } = require("../utils/index");
5 |
6 | const verfiyEmail = async (req, res) => {
7 | const { userId } = req.params;
8 | try {
9 | const result = await Verification.findOne({ userId });
10 | const { expires_At } = result;
11 | if (result) {
12 | if (expires_At < Date.now()) {
13 | await Verification.findOne({ userId })
14 | .then(() => {
15 | User.findOne({ _id: userId })
16 | .then(() => {
17 | const message = "Verification token has expaired";
18 | res.redirect(`/user/verified?status=error&message=${message}`);
19 | })
20 | .catch((error) => {
21 | res.redirect(`/user/verified?message=${error}`);
22 | });
23 | })
24 | .catch((error) => {
25 | res.redirect(`/user/verified?message=${error}`);
26 | });
27 | } else {
28 | decodePassword(userId, result.token)
29 | .then(async (isMatch) => {
30 | if (isMatch) {
31 | await User.findOneAndUpdate({ _id: userId }, { verified: true })
32 | .then((user) => {
33 | if(user){
34 | res.redirect(`/user/verified?status=success`);
35 | }
36 | })
37 | .catch((error) => {
38 | res.redirect(`/user/verified?status=fail`);
39 | });
40 | } else {
41 | res.redirect(`/user/verified?status=succes&message=${isMatch}`);
42 | }
43 | })
44 | .catch((error) => {
45 | res.redirect(`/user/verified?message=${error}`);
46 | });
47 | }
48 | }
49 | } catch (error) {
50 | res.status(201).json({ message: "user not exist" });
51 | }
52 | };
53 |
54 | module.exports = verfiyEmail;
55 |
--------------------------------------------------------------------------------
/server/controllers/users.js:
--------------------------------------------------------------------------------
1 | require('dotenv').config();
2 | const User = require("../models/userModels");
3 | const FriendRequest = require("../models/requestSchema");
4 | const cloudinary = require('cloudinary');
5 |
6 | const getUser = async (req, res) => {
7 | const { userId } = req.body.user;
8 | const { id } = req.params;
9 | const user = await User.findById(id ?? userId).populate({
10 | path: "friends",
11 | select: "-password",
12 | });
13 |
14 | if (user) {
15 | res.status(200).json({ data: user });
16 | } else {
17 | res.status(201).json({ message: "users not found" });
18 | }
19 | };
20 |
21 | const updateUser = async (req, res) => {
22 | const { userId } = req.body.user;
23 | const { data } = req.body;
24 |
25 | const filteredUser = Object.fromEntries(
26 | Object.entries(data).filter(([_, value]) => value !== "")
27 | );
28 | const updatedUser = await User.findByIdAndUpdate(
29 | { _id: userId },
30 | filteredUser
31 | );
32 |
33 | if (updatedUser) {
34 | res.status(200).json({ data: updatedUser });
35 | } else {
36 | res.status(201).json({ message: "users update fail" });
37 | }
38 | };
39 |
40 | const updateProfilePhoto = async (req, res) => {
41 | try {
42 | const { userId } = req.body.user;
43 | const { data } = req.body;
44 | if (!data) {
45 | return res.status(400).json({ message: "Provide all Fields" });
46 | }
47 | const user = await User.findOne({ _id: userId });
48 | if (!user) {
49 | return res.status(404).json({ message: "User not found" });
50 | }
51 | const deleteCloudinary = cloudinary.v2.api.delete_resources(user.profileUrl.public_id);
52 | user.profileUrl = data;
53 | const saveUser = user.save();
54 | await Promise.all([deleteCloudinary, saveUser]);
55 | res.status(200).json({ data: user });
56 | } catch (error) {
57 | console.error(error);
58 | res.status(500).json({ message: "Internal Server Error" });
59 | }
60 | };
61 |
62 | const sendfriendRequest = async (req, res, next) => {
63 | try {
64 | const { userId } = req.body.user;
65 | const { requestId } = req.body.data;
66 |
67 | const existRequest = await FriendRequest.findOne({
68 | requestFrom: userId,
69 | requestTo: requestId,
70 | });
71 |
72 | if (existRequest) {
73 | return res.status(201).json({ message: "You Have Alredy Sent Request" ,data:existRequest.status});
74 | }
75 |
76 | const accountExist = await FriendRequest.findOne({
77 | requestFrom: requestId,
78 | requestTo: userId,
79 | });
80 |
81 | if (accountExist) {
82 | return res.status(201).json({ message: "You Have Alredy Received Request",data:accountExist.status });
83 | }
84 |
85 | const newRequest = await FriendRequest.create({
86 | requestFrom: userId,
87 | requestTo: requestId,
88 | });
89 | newRequest.save();
90 | return res.status(200).json({ success: true, message: "Sent Request" });
91 | } catch (error) {
92 | return res.status(201).json({ success: true, message: "Sent Request Fail" });
93 | }
94 | };
95 |
96 | const getfriendRequest = async (req, res) => {
97 | const { userId } = req.body.user;
98 | try {
99 | const request = await FriendRequest.find({
100 | requestTo: userId,
101 | requestStatus: "Pending",
102 | })
103 | .populate({
104 | path: "requestFrom",
105 | select: "-password",
106 | })
107 | .limit(10)
108 | .sort({ _id: -1 });
109 | res.status(200).json({ success: true, data: request });
110 | } catch (error) {
111 | res.status(201).json({ message: "Not Exist" });
112 | }
113 | };
114 |
115 | const acceptfriendRequest = async (req, res) => {
116 | const id = req.body.user.userId;
117 | const { rid, requestStatus } = req.body.data;
118 | const status = requestStatus;
119 | const exist = await FriendRequest.findById(rid);
120 | if (!exist) {
121 | return res.status(201).json({ message: "No Friend requset found" });
122 | }
123 | try {
124 | const newExist = await FriendRequest.findByIdAndUpdate(
125 | { _id: rid, requestStatus: status },
126 | { requestStatus: "Accepted" },
127 | { new: true }
128 | );
129 |
130 | if (newExist && newExist.requestStatus === "Accepted") {
131 | const admin = await User.findById(id);
132 | const friendId = newExist.requestFrom;
133 |
134 | if (!admin.friends.includes(friendId)) {
135 | admin.friends.push(friendId);
136 | await admin.save();
137 | }
138 |
139 | const friend = await User.findById(friendId);
140 | if (!friend.friends.includes(id)) {
141 | friend.friends.push(id);
142 | await friend.save();
143 | }
144 | }
145 |
146 | res.status(200).json({
147 | success: true,
148 | message: "Friend Request Accepted",
149 | });
150 | } catch (error) {
151 | console.error(error);
152 | res.status(201).json({
153 | success: false,
154 | message: "An error occurred",
155 | });
156 | }
157 | };
158 |
159 | const profileView = async (req, res) => {
160 | const { userId } = req.body.user;
161 | const { id } = req.body;
162 | try {
163 | const user = await User.findById(id);
164 | user.views.push(userId);
165 | await user.save();
166 | res.status(200).json({
167 | success: true,
168 | message: "successfully viewd",
169 | });
170 | } catch (error) {
171 | res.status(201).json({ success: false, message: "failed" });
172 | }
173 | };
174 |
175 | const suggested = async (req, res) => {
176 | const { userId } = req.body.user;
177 | try {
178 | let queryObject = {};
179 | queryObject._id = { $ne: userId };
180 | queryObject.friends = { $nin: userId };
181 | queryObject.verified = true;
182 | let QueryResult = await User.find(queryObject)
183 | .limit(15)
184 | .select("-password");
185 | const suggestedFriends = QueryResult;
186 | res.status(200).json({ data: suggestedFriends, success: true });
187 | } catch (error) {
188 | res.status(201).json({ success: false, message: "failed" });
189 | }
190 | };
191 |
192 | const searchUser = async (req, res) => {
193 | try {
194 | const { search } = req.body;
195 | const posts = await User.find({
196 | firstname: { $regex: search, $options: "i" },
197 | });
198 | res.status(200).json({
199 | data: posts,
200 | success: true,
201 | message: "successfully",
202 | });
203 | } catch (error) {
204 | res.status(201).json({ message: "fail in get post" });
205 | }
206 | };
207 |
208 | const removeFriend = async (req, res) => {
209 | try {
210 | const userId = req.body.user.userId;
211 | const friendIdToRemove = req.body.data;
212 | await FriendRequest.findOneAndDelete({requestTo:friendIdToRemove,requestFrom:userId});
213 | await FriendRequest.findOneAndDelete({requestTo:userId,requestFrom:friendIdToRemove});
214 | const currentUser = await User.findById(userId);
215 | const friendIndex = currentUser.friends.indexOf(friendIdToRemove);
216 | if (friendIndex !== -1) {
217 | currentUser.friends.splice(friendIndex, 1);
218 | await currentUser.save();
219 | const friendUser = await User.findById(friendIdToRemove);
220 | const currentUserIndexInFriend = friendUser.friends.indexOf(userId);
221 | if (currentUserIndexInFriend !== -1) {
222 | friendUser.friends.splice(currentUserIndexInFriend, 1);
223 | await friendUser.save();
224 | return res.status(200).json({ message: `${friendUser.firstname} removed` });
225 | } else {
226 | return res.status(404).json({ message: "User not found in friend's friend list" });
227 | }
228 | } else {
229 | return res.status(404).json({ message: "Friend not found in user's friend list" });
230 | }
231 | } catch (error) {
232 | console.error(error);
233 | return res.status(500).json({ message: "Internal server error" });
234 | }
235 | };
236 |
237 |
238 | module.exports = {
239 | getUser,
240 | sendfriendRequest,
241 | getfriendRequest,
242 | acceptfriendRequest,
243 | profileView,
244 | suggested,
245 | updateUser,
246 | updateProfilePhoto,
247 | searchUser,
248 | removeFriend,
249 | };
250 |
--------------------------------------------------------------------------------
/server/middleware.js:
--------------------------------------------------------------------------------
1 | const jwt = require("jsonwebtoken");
2 | const userAuth = async (req, res, next) => {
3 | const authHead = req.body?.headers?.authorization;
4 | if (!authHead || !authHead?.startsWith("Bearer")) {
5 | next("Authentication === failed");
6 | }
7 | const token = authHead?.split(" ")[1];
8 | try {
9 | const payload = jwt.verify(token, process.env.JWT_SECRET_KEY);
10 | req.body.user = { userId: payload.userId };
11 | next();
12 | } catch (error) {
13 | next("authontication fail");
14 | }
15 | };
16 | module.exports = userAuth;
17 |
--------------------------------------------------------------------------------
/server/models/commentModel.js:
--------------------------------------------------------------------------------
1 | const mongoose = require("mongoose");
2 |
3 | const commentSchema = new mongoose.Schema(
4 | {
5 | userId: { type: mongoose.Schema.Types.ObjectId, ref: "user" },
6 | postId: { type: mongoose.Schema.Types.ObjectId, ref: "post" },
7 | comment: { type: String, require: true },
8 | from: { type: mongoose.Schema.Types.ObjectId, ref: "user" },
9 | replies: [
10 | {
11 | rId: { type: mongoose.Schema.Types.ObjectId },
12 | userId: { type: mongoose.Schema.Types.ObjectId, ref: "user" },
13 | from: { type: String },
14 | url: { type: String },
15 | replyAt: { type: String },
16 | comment: [String],
17 | created_At: { type: Date, default: Date.now() },
18 | replyed_At: { type: Date, default: Date.now() },
19 | likes: [String],
20 | },
21 | ],
22 | likes: [{ type: String }],
23 | },
24 | { timestamps: true }
25 | );
26 |
27 | const Comment = mongoose.model("comment", commentSchema);
28 | module.exports = Comment;
29 |
--------------------------------------------------------------------------------
/server/models/emailVerificatin.js:
--------------------------------------------------------------------------------
1 | const mongoose = require("mongoose");
2 |
3 | const emailVerificationSchema = new mongoose.Schema(
4 | {
5 | userId: String,
6 | token: String,
7 | created_At: Date,
8 | expires_At: Date,
9 | },
10 | { timestamps: true }
11 | );
12 |
13 | const Verification = mongoose.model(
14 | "emailVarification",
15 | emailVerificationSchema
16 | );
17 |
18 | module.exports = Verification;
19 |
--------------------------------------------------------------------------------
/server/models/passwordResetSchema.js:
--------------------------------------------------------------------------------
1 | const mongoose = require("mongoose");
2 |
3 | const passwordResetSchema = new mongoose.Schema({
4 | userId: { type: mongoose.Schema.Types.ObjectId, ref: "user" },
5 | email: { type: String, unique: true },
6 | token: { type: String },
7 | created_At: Date,
8 | expires_At: Date,
9 | });
10 |
11 | const PasswordReset = mongoose.model("passwordReset", passwordResetSchema);
12 |
13 | module.exports = PasswordReset;
14 |
--------------------------------------------------------------------------------
/server/models/postModel.js:
--------------------------------------------------------------------------------
1 | const mongoose = require("mongoose");
2 |
3 | const posrSchema = new mongoose.Schema(
4 | {
5 | userId: { type: mongoose.Schema.Types.ObjectId, ref: "user" },
6 | description: { type: String },
7 | image: { type: Object },
8 | likes: [String],
9 | comments: [{ type: mongoose.Schema.Types.ObjectId, ref: "comment" }],
10 | },
11 | { timestamps: true }
12 | );
13 |
14 | const Post = mongoose.model("post", posrSchema);
15 | module.exports = Post;
16 |
--------------------------------------------------------------------------------
/server/models/requestSchema.js:
--------------------------------------------------------------------------------
1 | const mongoose = require("mongoose");
2 |
3 | const requestSchema = new mongoose.Schema(
4 | {
5 | requestTo: { type: mongoose.Schema.Types.ObjectId, ref: "user" },
6 | requestFrom: { type: mongoose.Schema.Types.ObjectId, ref: "user" },
7 | requestStatus: { type: String, default: "Pending" },
8 | },
9 | { timestamps: true }
10 | );
11 |
12 | const FriendRequest = mongoose.model("friendRequest", requestSchema);
13 | module.exports = FriendRequest;
14 |
--------------------------------------------------------------------------------
/server/models/userModels.js:
--------------------------------------------------------------------------------
1 | const mongoose = require("mongoose");
2 |
3 | const userSchema = new mongoose.Schema(
4 | {
5 | firstname: {
6 | type: String,
7 | require: true,
8 | },
9 | lastname: {
10 | type: String,
11 | require: true,
12 | },
13 | email: {
14 | type: String,
15 | require: true,
16 | unique: true,
17 | },
18 | password: {
19 | type: String,
20 | require: true,
21 | min: 6,
22 | },
23 | gender: {
24 | type: String,
25 | },
26 | DOB: {
27 | type: Date,
28 | },
29 | location: {
30 | default: null,
31 | type: String,
32 | },
33 | profileUrl: {
34 | default: null,
35 | type: Object,
36 | },
37 | profession: {
38 | default: null,
39 | type: String,
40 | },
41 | views: [String],
42 | verified: { type: Boolean, default: false },
43 | friends: [{ type: mongoose.Schema.Types.ObjectId, ref: "user" }],
44 | },
45 | {
46 | timestamps: true,
47 | }
48 | );
49 |
50 | const User = mongoose.model("user", userSchema);
51 | module.exports = User;
52 |
--------------------------------------------------------------------------------
/server/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "server",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "server.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1",
8 | "start": "nodemon server.js"
9 | },
10 | "author": "\"hareesh dhruva\"",
11 | "license": "ISC",
12 | "dependencies": {
13 | "bcrypt": "^5.1.1",
14 | "body-parser": "^1.20.2",
15 | "cloudinary": "^2.0.0",
16 | "cookie-parser": "^1.4.6",
17 | "cors": "^2.8.5",
18 | "dotenv": "^16.3.1",
19 | "express": "^4.18.2",
20 | "ioredis": "^5.3.2",
21 | "jsonwebtoken": "^9.0.2",
22 | "mongoose": "^8.1.1",
23 | "mongoose-findorcreate": "^4.0.0",
24 | "morgan": "^1.10.0",
25 | "nodemailer": "^6.9.5",
26 | "nodemon": "^3.0.1",
27 | "otp-generator": "^4.0.1",
28 | "redis": "^4.6.11",
29 | "socket.io": "^4.7.4",
30 | "uuid": "^9.0.1"
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/server/routes/auth.js:
--------------------------------------------------------------------------------
1 | const express = require("express");
2 | const verfiyEmail = require("../controllers/userControl.js");
3 | const passworsReset = require("../controllers/passwordReset.js");
4 |
5 | const router = express.Router();
6 | router.get("/user/verify/:userId/:token", verfiyEmail);
7 | router.get("/user/password-reset/:userId/:token", passworsReset);
8 | module.exports = router;
9 |
--------------------------------------------------------------------------------
/server/server.js:
--------------------------------------------------------------------------------
1 | const dotenv = require("dotenv");
2 | const express = require("express");
3 | const bodyparser = require("body-parser");
4 | const cors = require("cors");
5 | const connection = require("./config");
6 |
7 | const {
8 | login,
9 | register,
10 | resetPasswordRequest,
11 | passwordChange,
12 | verifiedpasswordChange,
13 | logout,
14 | } = require("./controllers/authController");
15 | const router = require("./routes/auth");
16 | const path = require("path");
17 | const {
18 | getUser,
19 | sendfriendRequest,
20 | getfriendRequest,
21 | acceptfriendRequest,
22 | profileView,
23 | suggested,
24 | updateUser,
25 | updateProfilePhoto,
26 | searchUser,
27 | removeFriend,
28 | } = require("./controllers/users");
29 | const userAuth = require("./middleware");
30 | const {
31 | getPost,
32 | createPost,
33 | getuserPost,
34 | deletePost,
35 | } = require("./controllers/post");
36 | const {
37 | getComments,
38 | likeApost,
39 | likeAcomment,
40 | commentPost,
41 | replyPostComment,
42 | } = require("./controllers/comments");
43 |
44 | dotenv.config();
45 | const URL = process.env.MONGO_URL;
46 | const app = express();
47 | connection(URL);
48 |
49 | app.use(router);
50 | app.use(bodyparser.json({ extended: true }));
51 | app.use(bodyparser.urlencoded({ extended: true }));
52 |
53 | app.use(
54 | cors({
55 | origin: process.env.FRONTEND,
56 | credentials: true,
57 | })
58 | );
59 |
60 | app.post("/register", register);
61 | app.post("/login", login);
62 |
63 | app.get("/user/verify", router);
64 | app.get("/user/verified", (req, res) => {
65 | res.sendFile(path.join(__dirname, "./views/index.html"));
66 | });
67 |
68 | app.post("/user/password-reset-request", resetPasswordRequest);
69 | app.get("/user/password-reset", (req, res) => {
70 | res.sendFile(path.join(__dirname, "./views/passwordReset.html"));
71 | });
72 |
73 | app.post("/user/verified-password-change", verifiedpasswordChange);
74 | app.post("/user/password-change", passwordChange);
75 |
76 | app.post("/updateUser", userAuth, updateUser);
77 | app.post("/updateProfilePhoto", userAuth, updateProfilePhoto);
78 | app.post("/getuser/:id?", userAuth, getUser);
79 | app.post("/sendFriendRequest", userAuth, sendfriendRequest);
80 | app.post("/getFriendRequest", userAuth, getfriendRequest);
81 | app.post("/acceptFriendRequest", userAuth, acceptfriendRequest);
82 | app.post("/profileView", userAuth, profileView); //not
83 | app.post("/suggested", userAuth, suggested);
84 | app.post("/searchUser", searchUser);
85 | app.post("/deleteFriend", userAuth, removeFriend);
86 |
87 | app.get("/", getPost);
88 | app.post("/create-post", userAuth, createPost);
89 | app.post("/get-user-post/:id", userAuth, getuserPost);
90 | app.post("/delete-post/:id", userAuth, deletePost);
91 |
92 | app.get("/comment/:postId", getComments);
93 | app.post("/like/:id", userAuth, likeApost);
94 | app.post("/like-comment/:id/:rid?", userAuth, likeAcomment);
95 | app.post("/comment-post/:id", userAuth, commentPost);
96 | app.post("/reply-comment/:id", userAuth, replyPostComment);
97 |
98 | app.post("/logout", logout); //not
99 | app.listen(process.env.PORT, () => {
100 | console.log(`main server started`);
101 | });
102 |
--------------------------------------------------------------------------------
/server/utils/index.js:
--------------------------------------------------------------------------------
1 | const bcrypt = require('bcrypt')
2 | const jwt = require('jsonwebtoken');
3 |
4 | const hasing = async(userValue) =>{
5 | const salt = await bcrypt.genSalt(10);
6 | const hasedPassword = await bcrypt.hash(userValue,salt)
7 | return hasedPassword;
8 | }
9 |
10 | function createJWT(id){
11 | const token = jwt.sign({userId:id},process.env.JWT_SECRET_KEY,{expiresIn:"1d"});
12 | return token;
13 | }
14 |
15 | async function decodePassword(userId,hasedToken){
16 | const payload = jwt.decode(hasedToken)
17 | if(payload.userId === userId){
18 | return true;
19 | }
20 | if(err){
21 | return false;
22 | }
23 | }
24 |
25 | async function comparePassword(password,hasedPassword){
26 | const validPass = await bcrypt.compare(password,hasedPassword);
27 | if(validPass){
28 | return true;
29 | }
30 | else{
31 | return false;
32 | }
33 | }
34 |
35 | module.exports = {hasing,createJWT,decodePassword,comparePassword};
--------------------------------------------------------------------------------
/server/utils/passwordChange.js:
--------------------------------------------------------------------------------
1 | const nodemailer = require("nodemailer");
2 | const transporter = nodemailer.createTransport({
3 | service: "gmail",
4 | port: 587,
5 | auth: {
6 | user: "hareeshdhruva143@gmail.com",
7 | pass: "qxvw xxnp jucp wvre",
8 | },
9 | });
10 |
11 | const sendPasswordchangeEmail = async (user, res) => {
12 | const { email, firstname, lastname } = user;
13 | if (!email || !firstname || !lastname) {
14 | return res.status(404).json({ message: "user not found to send message" });
15 | }
16 | try {
17 | await transporter.sendMail({
18 | from: '"OSM 👻" ',
19 | to: email,
20 | subject: "Password Change",
21 | text: "Hello",
22 | html: `
23 |
24 |
25 |
26 |
27 |
28 | Password change
29 |
59 |
60 |
61 |
62 |
Hello ${firstname + " " + lastname}
63 |
64 |
65 |
Your request to change the Password has been Successfully completed!
66 |
67 |
68 |
69 | `,
70 | });
71 |
72 | res.status(200).json({ message: "Password Change Sucessfully" });
73 | } catch (error) {
74 | console.log(error);
75 | res.status(201).json({ message: "Something Went Wrong" });
76 | }
77 | };
78 | module.exports = { sendPasswordchangeEmail };
79 |
--------------------------------------------------------------------------------
/server/utils/passwordResetRequest.js:
--------------------------------------------------------------------------------
1 | const nodemailer = require("nodemailer");
2 | const passwordReset = require("../models/passwordResetSchema");
3 | const { createJWT } = require("./index");
4 | const { v4: uuidv4 } = require("uuid");
5 | const { use } = require("bcrypt/promises");
6 |
7 | const transporter = nodemailer.createTransport({
8 | service: "gmail",
9 | port: 587,
10 | auth: {
11 | user: "hareeshdhruva143@gmail.com",
12 | pass: "qxvw xxnp jucp wvre",
13 | },
14 | });
15 |
16 | const sendPasswordReset = async (user, res) => {
17 | const { _id, email, firstname, lastname } = user;
18 | const token = _id + uuidv4();
19 | const link =
20 | process.env.APP_URL + "/user/password-reset/" + _id + "/" + token;
21 | try {
22 | const info = await transporter.sendMail({
23 | from: '"OSM 👻" ',
24 | to: email,
25 | subject: "Password Reset",
26 | text: "Hello",
27 | html: `
28 |
29 |
30 |
31 |
32 |
33 | Password request
34 |
84 |
85 |
86 |
87 |
${firstname + " " + lastname}
88 |
Thank you for Password Reset service! Please click the button below to reset your password:
89 |
Reset Password
90 |
91 |
92 |
93 | `,
94 | });
95 | try {
96 | const jwtToken = createJWT(_id);
97 | const user = await passwordReset.findOneAndUpdate(
98 | { userId: _id },
99 | {
100 | userId: _id,
101 | token: jwtToken,
102 | email,
103 | created_At: Date.now(),
104 | expires_At: Date.now() + 3600000,
105 | }
106 | );
107 | if (user) {
108 | return res
109 | .status(200)
110 | .json({ message: "Check Your Mail Already Sent" });
111 | }
112 |
113 | const newRequestReset = await passwordReset.create({
114 | userId: _id,
115 | token: jwtToken,
116 | email,
117 | created_At: Date.now(),
118 | expires_At: Date.now() + 3600000,
119 | });
120 |
121 | if (!newRequestReset) {
122 | transporter.sendMail(info).then(() => {
123 | res.status(200).json({ message: "Check Your Mail Already Sent" ,data:link});
124 | });
125 | }
126 | } catch (error) {
127 | console.log(error);
128 | }
129 | res.status(200).json({ message: "Sucessfully Send Reset Mail",data:link});
130 | } catch (error) {
131 | console.log(error);
132 | }
133 | };
134 | module.exports = { sendPasswordReset };
135 |
--------------------------------------------------------------------------------
/server/utils/sendVerification.js:
--------------------------------------------------------------------------------
1 | const nodemailer = require("nodemailer");
2 | const verification = require("../models/emailVerificatin");
3 | const { createJWT } = require(".");
4 | const { v4: uuidv4 } = require("uuid");
5 |
6 | const transporter = nodemailer.createTransport({
7 | service: "gmail",
8 | port: 587,
9 | auth: {
10 | user: "hareeshdhruva143@gmail.com",
11 | pass: "qxvw xxnp jucp wvre",
12 | },
13 | });
14 |
15 | const sendNotififcation = async (user, res) => {
16 | const { _id, email, firstname, lastname } = user;
17 | const token = _id + uuidv4();
18 | const link = process.env.APP_URL + "/user/verify/" + _id + "/" + token;
19 | try {
20 | const info = await transporter.sendMail({
21 | from: '"OSM 👻" ',
22 | to: email,
23 | subject: "Email verification",
24 | text: "Hello",
25 | html: `
26 |
27 |
28 |
29 |
30 |
31 | Email Confirmation
32 |
81 |
82 |
83 |
84 |
${firstname + " " + lastname}
85 |
Thank you for signing up! Please click the button below to confirm your email address:
86 |
Confirm Email
87 |
88 |
89 |
90 | `,
91 | });
92 | try {
93 | const jwtToken = createJWT(_id);
94 | const newVerifiedEmail = await verification.create({
95 | userId: _id,
96 | token: jwtToken,
97 | created_At: Date.now(),
98 | expires_At: Date.now() + 3600000,
99 | });
100 | if (!newVerifiedEmail) {
101 | transporter.sendMail(info).then(() => {
102 | res.status(201).send({
103 | success: "Pending",
104 | message:
105 | "Verification email has been sent to your email for verification",
106 | });
107 | });
108 | }
109 | } catch (error) {
110 | console.log(error);
111 | }
112 | res.status(200).json({ data: link, message: "Verify Email Address" });
113 | } catch (error) {
114 | console.log(error);
115 | }
116 | };
117 | module.exports = { sendNotififcation };
118 |
--------------------------------------------------------------------------------
/server/vercel.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": 2,
3 | "builds": [
4 | {
5 | "src": "server.js",
6 | "use": "@vercel/node"
7 | }
8 | ],
9 | "routes": [
10 | { "src": "/(.*)", "dest": "server.js" }
11 | ]
12 | }
13 |
--------------------------------------------------------------------------------
/server/views/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
10 | confirmation
11 |
64 |
65 |
66 |
67 |
Email Confirmation Success
68 |
69 | Thank you for signing up! Please click the button below to confirm your
70 | email address:
71 |
72 |
Login
75 |
76 |
77 |
78 |
Email Confirmation Fail
79 |
somethis went wrong! Request foe new Confirmation mail address
80 |
Re-try
83 |
84 |
105 |
106 |
107 |
--------------------------------------------------------------------------------
/server/views/passwordReset.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
10 | Password Reset
11 |
94 |
95 |
96 |
97 |
Password Reset
98 |
116 |
117 |
118 |
Reset Success
119 |
120 |
Thank you
121 |
close
124 |
125 |
126 |
183 |
184 |
185 |
--------------------------------------------------------------------------------