├── src
├── utils
│ ├── test.js
│ ├── Portal.js
│ ├── isRTL.js
│ ├── radialToLinearGradient.js
│ ├── useOnClickOutside.js
│ ├── messagesPosition.js
│ └── dataURItoBlob.js
├── pages
│ ├── login
│ │ ├── style.module.css
│ │ └── index.jsx
│ ├── forgot
│ │ ├── style.module.css
│ │ └── index.jsx
│ ├── post
│ │ ├── style.module.css
│ │ └── PostPage.jsx
│ ├── messages
│ │ ├── SeenStatus.jsx
│ │ └── index.jsx
│ ├── profile
│ │ ├── ProfileMenu.jsx
│ │ ├── Photos.jsx
│ │ └── Friends.jsx
│ ├── home
│ │ └── style.module.css
│ └── friends
│ │ └── FreindCard.jsx
├── assets
│ ├── chat_notification.wav
│ └── notification_sweet.wav
├── components
│ ├── UI
│ │ ├── Card
│ │ │ ├── Card.module.css
│ │ │ └── Card.jsx
│ │ ├── Loading
│ │ │ ├── Loading.module.css
│ │ │ └── Loading.jsx
│ │ ├── Error
│ │ │ ├── ErrorPage.module.css
│ │ │ └── ErrorPage.jsx
│ │ └── Notification
│ │ │ ├── Notification.module.css
│ │ │ └── Notification.jsx
│ ├── home
│ │ ├── left
│ │ │ ├── Shortcut.jsx
│ │ │ └── LeftLink.jsx
│ │ ├── right
│ │ │ ├── Contact.jsx
│ │ │ ├── HomeRight.jsx
│ │ │ └── HomeRight.module.css
│ │ ├── stories
│ │ │ ├── Story.jsx
│ │ │ └── Stories.jsx
│ │ ├── SendVerification
│ │ │ ├── SendVerification.module.css
│ │ │ └── SendVerification.jsx
│ │ └── posts
│ │ │ └── CreatePost
│ │ │ ├── CreatePost.jsx
│ │ │ └── CreatePost.module.css
│ ├── header
│ │ ├── AllMenuItem.jsx
│ │ ├── userMenu
│ │ │ ├── HelpSupport.jsx
│ │ │ └── SettingsPrivacy.jsx
│ │ └── notificationMenu
│ │ │ └── NotificationMenu.module.css
│ ├── noAuthHeader
│ │ ├── style.module.css
│ │ └── index.jsx
│ ├── posts
│ │ ├── post
│ │ │ ├── MenuItem.jsx
│ │ │ ├── likes
│ │ │ │ ├── ReactsPopup.module.css
│ │ │ │ └── ReactsPopup.jsx
│ │ │ ├── shares
│ │ │ │ ├── CreateSharePost.module.css
│ │ │ │ └── ShareMenu.jsx
│ │ │ └── comments
│ │ │ │ ├── CreateComment.module.css
│ │ │ │ └── Comments.jsx
│ │ └── CreatePostPopup
│ │ │ └── AddToYourPost.jsx
│ ├── messages
│ │ ├── chatInfo
│ │ │ ├── chatInfo.module.css
│ │ │ └── chatInfo.jsx
│ │ ├── chatTheme
│ │ │ └── ChatTheme.module.css
│ │ ├── createGroup
│ │ │ └── CreateGroup.module.css
│ │ └── SearchUser.module.css
│ ├── input
│ │ ├── login
│ │ │ ├── input.module.css
│ │ │ └── index.jsx
│ │ └── signup
│ │ │ ├── style.module.css
│ │ │ └── index.jsx
│ ├── ActivateAccount
│ │ └── ActivateAccount.module.css
│ ├── login
│ │ ├── LoginFooter.module.css
│ │ ├── LoginForm.module.css
│ │ ├── GenderSelector.jsx
│ │ ├── LoginFooter.jsx
│ │ └── SignupForm.module.css
│ ├── profile
│ │ ├── cover
│ │ │ ├── OldCovers.module.css
│ │ │ ├── Cover.module.css
│ │ │ └── OldCovers.jsx
│ │ └── intro
│ │ │ ├── EditDetails.module.css
│ │ │ ├── Detail.jsx
│ │ │ ├── intro.module.css
│ │ │ └── EditArea.jsx
│ ├── FormLoader
│ │ ├── style.module.css
│ │ └── index.jsx
│ ├── skeleton
│ │ └── PostSkeleton.jsx
│ ├── Popper
│ │ └── Popper.jsx
│ └── forgot
│ │ └── SendEmail.jsx
├── app
│ ├── store.js
│ └── slices
│ │ ├── soketSlice.js
│ │ └── createPostSlice.js
├── routes
│ ├── NotLoggedIn.js
│ ├── router.jsx
│ └── pagesData.jsx
├── svg
│ ├── arrowDown.js
│ ├── dots.js
│ ├── arrowDow1.js
│ ├── gaming.js
│ ├── unseen.js
│ ├── plus.js
│ ├── watch.js
│ ├── menu.js
│ ├── homeActive.js
│ ├── messenger.js
│ ├── notifications.js
│ ├── friendsActive.js
│ ├── arrowRight.js
│ ├── return.js
│ ├── newRoom.js
│ ├── info.js
│ ├── home.js
│ ├── like.js
│ ├── send.js
│ ├── liveVideo.js
│ ├── friends.js
│ ├── smile.js
│ ├── feeling.js
│ ├── photo.js
│ ├── index.js
│ ├── market.js
│ ├── phone.js
│ ├── public.js
│ └── search.js
├── data
│ └── post.js
├── styles
│ └── dark.css
├── hooks
│ ├── useSearch.js
│ ├── useGetChat.js
│ ├── useDeletePost.js
│ ├── useAddToSearch.js
│ ├── useRemoveFromSearch.js
│ ├── useAddFCM.js
│ ├── useOnClickOutside.js
│ ├── useWindowDimensions .js
│ ├── useReaction.js
│ ├── useCommentLike.js
│ ├── useComment.js
│ ├── useCreateChatGroup.js
│ ├── useSeenMessage.js
│ ├── useRealationship.js
│ ├── useSendMessage.js
│ ├── useRenameGroup.js
│ ├── useSeenNotification.js
│ ├── useAddMember.js
│ ├── useCreatePost.js
│ ├── useRemoveMember.js
│ └── useChangeTheme.js
├── fcm.js
├── index.js
└── App.js
├── public
├── left
│ ├── ad.png
│ ├── ads.png
│ ├── fav.png
│ ├── feed.png
│ ├── fund.png
│ ├── jobs.png
│ ├── live.png
│ ├── pay.png
│ ├── play.png
│ ├── campus.png
│ ├── climate.png
│ ├── covid.png
│ ├── events.png
│ ├── friends.png
│ ├── gaming.png
│ ├── groups.png
│ ├── pages.png
│ ├── recent.png
│ ├── saved.png
│ ├── watch.png
│ ├── weather.png
│ ├── community.png
│ ├── emotional.png
│ ├── memories.png
│ ├── messenger.png
│ ├── messkids.png
│ ├── recentad.png
│ ├── fundraisers.png
│ └── marketplace.png
├── google6a1d9096156ee381.html
├── icons
│ ├── fb.png
│ ├── job.png
│ ├── follow.png
│ ├── from.png
│ ├── home.png
│ ├── icon.png
│ ├── icons1.png
│ ├── icons2.png
│ ├── icons3.png
│ ├── icons4.png
│ ├── icons5.png
│ ├── icons6.png
│ ├── icons7.png
│ ├── icons8.png
│ ├── icons9.png
│ ├── join.png
│ ├── lock.png
│ ├── plus.png
│ ├── public.png
│ ├── report.png
│ ├── colorful.png
│ ├── friends.png
│ ├── hometown.png
│ ├── icons10.png
│ ├── icons11.png
│ ├── icons12.png
│ ├── icons13.png
│ ├── icons14.png
│ ├── icons15.png
│ ├── icons16.png
│ ├── icons17.png
│ ├── icons18.png
│ ├── icons19.png
│ ├── icons20.png
│ ├── icons21.png
│ ├── icons22.png
│ ├── icons23.png
│ ├── icons24.png
│ ├── icons25.png
│ ├── icons26.png
│ ├── icons27.png
│ ├── icons28.png
│ ├── icons29.png
│ ├── icons30.png
│ ├── icons31.png
│ ├── icons32.png
│ ├── icons33.png
│ ├── icons34.png
│ ├── icons35.png
│ ├── icons36.png
│ ├── icons37.png
│ ├── icons38.png
│ ├── icons39.png
│ ├── icons40.png
│ ├── icons41.png
│ ├── message.png
│ ├── refresh.png
│ ├── studies.png
│ ├── addFriend.png
│ ├── editFriends.png
│ ├── following.png
│ ├── instagram.png
│ ├── publicpack.png
│ ├── backbook-icon.png
│ ├── cancelRequest.png
│ ├── relationship.png
│ ├── favoritesOutline.png
│ ├── unfollowOutlined.png
│ ├── facebook.svg
│ └── backbook.svg
├── images
│ ├── insta.png
│ ├── ytb.png
│ ├── github.png
│ ├── linkedin.png
│ ├── background.webp
│ ├── default_pic.png
│ ├── default_profile.png
│ └── postBackgrounds
│ │ ├── 1.jpg
│ │ ├── 2.jpg
│ │ ├── 3.jpg
│ │ ├── 4.jpg
│ │ ├── 5.jpg
│ │ ├── 6.jpg
│ │ ├── 7.jpg
│ │ ├── 8.jpg
│ │ ├── 9.jpg
│ │ └── 10.jpg
├── reacts
│ ├── angry.gif
│ ├── haha.gif
│ ├── like.gif
│ ├── like.png
│ ├── love.gif
│ ├── sad.gif
│ ├── wow.gif
│ ├── love.svg
│ ├── like.svg
│ └── haha.svg
├── robots.txt
├── stories
│ ├── 1.webp
│ ├── 2.webp
│ ├── 3.webp
│ ├── 4.webp
│ ├── 5.webp
│ ├── profile1.webp
│ ├── profile2.webp
│ ├── profile3.webp
│ ├── profile4.webp
│ └── profile5.webp
├── manifest.json
├── index.html
└── firebase-messaging-sw.js
├── .gitignore
├── .vscode
└── settings.json
└── package.json
/src/utils/test.js:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/public/left/ad.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msobkyy/backbook/HEAD/public/left/ad.png
--------------------------------------------------------------------------------
/public/google6a1d9096156ee381.html:
--------------------------------------------------------------------------------
1 | google-site-verification: google6a1d9096156ee381.html
2 |
--------------------------------------------------------------------------------
/public/icons/fb.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msobkyy/backbook/HEAD/public/icons/fb.png
--------------------------------------------------------------------------------
/public/icons/job.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msobkyy/backbook/HEAD/public/icons/job.png
--------------------------------------------------------------------------------
/public/left/ads.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msobkyy/backbook/HEAD/public/left/ads.png
--------------------------------------------------------------------------------
/public/left/fav.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msobkyy/backbook/HEAD/public/left/fav.png
--------------------------------------------------------------------------------
/public/left/feed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msobkyy/backbook/HEAD/public/left/feed.png
--------------------------------------------------------------------------------
/public/left/fund.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msobkyy/backbook/HEAD/public/left/fund.png
--------------------------------------------------------------------------------
/public/left/jobs.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msobkyy/backbook/HEAD/public/left/jobs.png
--------------------------------------------------------------------------------
/public/left/live.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msobkyy/backbook/HEAD/public/left/live.png
--------------------------------------------------------------------------------
/public/left/pay.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msobkyy/backbook/HEAD/public/left/pay.png
--------------------------------------------------------------------------------
/public/left/play.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msobkyy/backbook/HEAD/public/left/play.png
--------------------------------------------------------------------------------
/src/pages/login/style.module.css:
--------------------------------------------------------------------------------
1 | .wrapper {
2 | background: var(--bg-secondary);
3 | }
4 |
--------------------------------------------------------------------------------
/public/icons/follow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msobkyy/backbook/HEAD/public/icons/follow.png
--------------------------------------------------------------------------------
/public/icons/from.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msobkyy/backbook/HEAD/public/icons/from.png
--------------------------------------------------------------------------------
/public/icons/home.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msobkyy/backbook/HEAD/public/icons/home.png
--------------------------------------------------------------------------------
/public/icons/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msobkyy/backbook/HEAD/public/icons/icon.png
--------------------------------------------------------------------------------
/public/icons/icons1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msobkyy/backbook/HEAD/public/icons/icons1.png
--------------------------------------------------------------------------------
/public/icons/icons2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msobkyy/backbook/HEAD/public/icons/icons2.png
--------------------------------------------------------------------------------
/public/icons/icons3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msobkyy/backbook/HEAD/public/icons/icons3.png
--------------------------------------------------------------------------------
/public/icons/icons4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msobkyy/backbook/HEAD/public/icons/icons4.png
--------------------------------------------------------------------------------
/public/icons/icons5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msobkyy/backbook/HEAD/public/icons/icons5.png
--------------------------------------------------------------------------------
/public/icons/icons6.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msobkyy/backbook/HEAD/public/icons/icons6.png
--------------------------------------------------------------------------------
/public/icons/icons7.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msobkyy/backbook/HEAD/public/icons/icons7.png
--------------------------------------------------------------------------------
/public/icons/icons8.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msobkyy/backbook/HEAD/public/icons/icons8.png
--------------------------------------------------------------------------------
/public/icons/icons9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msobkyy/backbook/HEAD/public/icons/icons9.png
--------------------------------------------------------------------------------
/public/icons/join.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msobkyy/backbook/HEAD/public/icons/join.png
--------------------------------------------------------------------------------
/public/icons/lock.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msobkyy/backbook/HEAD/public/icons/lock.png
--------------------------------------------------------------------------------
/public/icons/plus.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msobkyy/backbook/HEAD/public/icons/plus.png
--------------------------------------------------------------------------------
/public/icons/public.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msobkyy/backbook/HEAD/public/icons/public.png
--------------------------------------------------------------------------------
/public/icons/report.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msobkyy/backbook/HEAD/public/icons/report.png
--------------------------------------------------------------------------------
/public/images/insta.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msobkyy/backbook/HEAD/public/images/insta.png
--------------------------------------------------------------------------------
/public/images/ytb.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msobkyy/backbook/HEAD/public/images/ytb.png
--------------------------------------------------------------------------------
/public/left/campus.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msobkyy/backbook/HEAD/public/left/campus.png
--------------------------------------------------------------------------------
/public/left/climate.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msobkyy/backbook/HEAD/public/left/climate.png
--------------------------------------------------------------------------------
/public/left/covid.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msobkyy/backbook/HEAD/public/left/covid.png
--------------------------------------------------------------------------------
/public/left/events.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msobkyy/backbook/HEAD/public/left/events.png
--------------------------------------------------------------------------------
/public/left/friends.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msobkyy/backbook/HEAD/public/left/friends.png
--------------------------------------------------------------------------------
/public/left/gaming.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msobkyy/backbook/HEAD/public/left/gaming.png
--------------------------------------------------------------------------------
/public/left/groups.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msobkyy/backbook/HEAD/public/left/groups.png
--------------------------------------------------------------------------------
/public/left/pages.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msobkyy/backbook/HEAD/public/left/pages.png
--------------------------------------------------------------------------------
/public/left/recent.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msobkyy/backbook/HEAD/public/left/recent.png
--------------------------------------------------------------------------------
/public/left/saved.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msobkyy/backbook/HEAD/public/left/saved.png
--------------------------------------------------------------------------------
/public/left/watch.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msobkyy/backbook/HEAD/public/left/watch.png
--------------------------------------------------------------------------------
/public/left/weather.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msobkyy/backbook/HEAD/public/left/weather.png
--------------------------------------------------------------------------------
/public/reacts/angry.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msobkyy/backbook/HEAD/public/reacts/angry.gif
--------------------------------------------------------------------------------
/public/reacts/haha.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msobkyy/backbook/HEAD/public/reacts/haha.gif
--------------------------------------------------------------------------------
/public/reacts/like.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msobkyy/backbook/HEAD/public/reacts/like.gif
--------------------------------------------------------------------------------
/public/reacts/like.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msobkyy/backbook/HEAD/public/reacts/like.png
--------------------------------------------------------------------------------
/public/reacts/love.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msobkyy/backbook/HEAD/public/reacts/love.gif
--------------------------------------------------------------------------------
/public/reacts/sad.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msobkyy/backbook/HEAD/public/reacts/sad.gif
--------------------------------------------------------------------------------
/public/reacts/wow.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msobkyy/backbook/HEAD/public/reacts/wow.gif
--------------------------------------------------------------------------------
/public/robots.txt:
--------------------------------------------------------------------------------
1 | # https://www.robotstxt.org/robotstxt.html
2 | User-agent: *
3 | Disallow:
4 |
--------------------------------------------------------------------------------
/public/stories/1.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msobkyy/backbook/HEAD/public/stories/1.webp
--------------------------------------------------------------------------------
/public/stories/2.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msobkyy/backbook/HEAD/public/stories/2.webp
--------------------------------------------------------------------------------
/public/stories/3.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msobkyy/backbook/HEAD/public/stories/3.webp
--------------------------------------------------------------------------------
/public/stories/4.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msobkyy/backbook/HEAD/public/stories/4.webp
--------------------------------------------------------------------------------
/public/stories/5.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msobkyy/backbook/HEAD/public/stories/5.webp
--------------------------------------------------------------------------------
/public/icons/colorful.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msobkyy/backbook/HEAD/public/icons/colorful.png
--------------------------------------------------------------------------------
/public/icons/friends.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msobkyy/backbook/HEAD/public/icons/friends.png
--------------------------------------------------------------------------------
/public/icons/hometown.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msobkyy/backbook/HEAD/public/icons/hometown.png
--------------------------------------------------------------------------------
/public/icons/icons10.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msobkyy/backbook/HEAD/public/icons/icons10.png
--------------------------------------------------------------------------------
/public/icons/icons11.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msobkyy/backbook/HEAD/public/icons/icons11.png
--------------------------------------------------------------------------------
/public/icons/icons12.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msobkyy/backbook/HEAD/public/icons/icons12.png
--------------------------------------------------------------------------------
/public/icons/icons13.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msobkyy/backbook/HEAD/public/icons/icons13.png
--------------------------------------------------------------------------------
/public/icons/icons14.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msobkyy/backbook/HEAD/public/icons/icons14.png
--------------------------------------------------------------------------------
/public/icons/icons15.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msobkyy/backbook/HEAD/public/icons/icons15.png
--------------------------------------------------------------------------------
/public/icons/icons16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msobkyy/backbook/HEAD/public/icons/icons16.png
--------------------------------------------------------------------------------
/public/icons/icons17.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msobkyy/backbook/HEAD/public/icons/icons17.png
--------------------------------------------------------------------------------
/public/icons/icons18.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msobkyy/backbook/HEAD/public/icons/icons18.png
--------------------------------------------------------------------------------
/public/icons/icons19.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msobkyy/backbook/HEAD/public/icons/icons19.png
--------------------------------------------------------------------------------
/public/icons/icons20.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msobkyy/backbook/HEAD/public/icons/icons20.png
--------------------------------------------------------------------------------
/public/icons/icons21.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msobkyy/backbook/HEAD/public/icons/icons21.png
--------------------------------------------------------------------------------
/public/icons/icons22.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msobkyy/backbook/HEAD/public/icons/icons22.png
--------------------------------------------------------------------------------
/public/icons/icons23.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msobkyy/backbook/HEAD/public/icons/icons23.png
--------------------------------------------------------------------------------
/public/icons/icons24.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msobkyy/backbook/HEAD/public/icons/icons24.png
--------------------------------------------------------------------------------
/public/icons/icons25.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msobkyy/backbook/HEAD/public/icons/icons25.png
--------------------------------------------------------------------------------
/public/icons/icons26.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msobkyy/backbook/HEAD/public/icons/icons26.png
--------------------------------------------------------------------------------
/public/icons/icons27.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msobkyy/backbook/HEAD/public/icons/icons27.png
--------------------------------------------------------------------------------
/public/icons/icons28.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msobkyy/backbook/HEAD/public/icons/icons28.png
--------------------------------------------------------------------------------
/public/icons/icons29.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msobkyy/backbook/HEAD/public/icons/icons29.png
--------------------------------------------------------------------------------
/public/icons/icons30.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msobkyy/backbook/HEAD/public/icons/icons30.png
--------------------------------------------------------------------------------
/public/icons/icons31.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msobkyy/backbook/HEAD/public/icons/icons31.png
--------------------------------------------------------------------------------
/public/icons/icons32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msobkyy/backbook/HEAD/public/icons/icons32.png
--------------------------------------------------------------------------------
/public/icons/icons33.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msobkyy/backbook/HEAD/public/icons/icons33.png
--------------------------------------------------------------------------------
/public/icons/icons34.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msobkyy/backbook/HEAD/public/icons/icons34.png
--------------------------------------------------------------------------------
/public/icons/icons35.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msobkyy/backbook/HEAD/public/icons/icons35.png
--------------------------------------------------------------------------------
/public/icons/icons36.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msobkyy/backbook/HEAD/public/icons/icons36.png
--------------------------------------------------------------------------------
/public/icons/icons37.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msobkyy/backbook/HEAD/public/icons/icons37.png
--------------------------------------------------------------------------------
/public/icons/icons38.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msobkyy/backbook/HEAD/public/icons/icons38.png
--------------------------------------------------------------------------------
/public/icons/icons39.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msobkyy/backbook/HEAD/public/icons/icons39.png
--------------------------------------------------------------------------------
/public/icons/icons40.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msobkyy/backbook/HEAD/public/icons/icons40.png
--------------------------------------------------------------------------------
/public/icons/icons41.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msobkyy/backbook/HEAD/public/icons/icons41.png
--------------------------------------------------------------------------------
/public/icons/message.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msobkyy/backbook/HEAD/public/icons/message.png
--------------------------------------------------------------------------------
/public/icons/refresh.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msobkyy/backbook/HEAD/public/icons/refresh.png
--------------------------------------------------------------------------------
/public/icons/studies.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msobkyy/backbook/HEAD/public/icons/studies.png
--------------------------------------------------------------------------------
/public/images/github.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msobkyy/backbook/HEAD/public/images/github.png
--------------------------------------------------------------------------------
/public/left/community.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msobkyy/backbook/HEAD/public/left/community.png
--------------------------------------------------------------------------------
/public/left/emotional.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msobkyy/backbook/HEAD/public/left/emotional.png
--------------------------------------------------------------------------------
/public/left/memories.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msobkyy/backbook/HEAD/public/left/memories.png
--------------------------------------------------------------------------------
/public/left/messenger.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msobkyy/backbook/HEAD/public/left/messenger.png
--------------------------------------------------------------------------------
/public/left/messkids.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msobkyy/backbook/HEAD/public/left/messkids.png
--------------------------------------------------------------------------------
/public/left/recentad.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msobkyy/backbook/HEAD/public/left/recentad.png
--------------------------------------------------------------------------------
/public/icons/addFriend.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msobkyy/backbook/HEAD/public/icons/addFriend.png
--------------------------------------------------------------------------------
/public/icons/editFriends.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msobkyy/backbook/HEAD/public/icons/editFriends.png
--------------------------------------------------------------------------------
/public/icons/following.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msobkyy/backbook/HEAD/public/icons/following.png
--------------------------------------------------------------------------------
/public/icons/instagram.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msobkyy/backbook/HEAD/public/icons/instagram.png
--------------------------------------------------------------------------------
/public/icons/publicpack.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msobkyy/backbook/HEAD/public/icons/publicpack.png
--------------------------------------------------------------------------------
/public/images/linkedin.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msobkyy/backbook/HEAD/public/images/linkedin.png
--------------------------------------------------------------------------------
/public/left/fundraisers.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msobkyy/backbook/HEAD/public/left/fundraisers.png
--------------------------------------------------------------------------------
/public/left/marketplace.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msobkyy/backbook/HEAD/public/left/marketplace.png
--------------------------------------------------------------------------------
/public/stories/profile1.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msobkyy/backbook/HEAD/public/stories/profile1.webp
--------------------------------------------------------------------------------
/public/stories/profile2.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msobkyy/backbook/HEAD/public/stories/profile2.webp
--------------------------------------------------------------------------------
/public/stories/profile3.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msobkyy/backbook/HEAD/public/stories/profile3.webp
--------------------------------------------------------------------------------
/public/stories/profile4.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msobkyy/backbook/HEAD/public/stories/profile4.webp
--------------------------------------------------------------------------------
/public/stories/profile5.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msobkyy/backbook/HEAD/public/stories/profile5.webp
--------------------------------------------------------------------------------
/public/icons/backbook-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msobkyy/backbook/HEAD/public/icons/backbook-icon.png
--------------------------------------------------------------------------------
/public/icons/cancelRequest.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msobkyy/backbook/HEAD/public/icons/cancelRequest.png
--------------------------------------------------------------------------------
/public/icons/relationship.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msobkyy/backbook/HEAD/public/icons/relationship.png
--------------------------------------------------------------------------------
/public/images/background.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msobkyy/backbook/HEAD/public/images/background.webp
--------------------------------------------------------------------------------
/public/images/default_pic.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msobkyy/backbook/HEAD/public/images/default_pic.png
--------------------------------------------------------------------------------
/public/icons/favoritesOutline.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msobkyy/backbook/HEAD/public/icons/favoritesOutline.png
--------------------------------------------------------------------------------
/public/icons/unfollowOutlined.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msobkyy/backbook/HEAD/public/icons/unfollowOutlined.png
--------------------------------------------------------------------------------
/public/images/default_profile.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msobkyy/backbook/HEAD/public/images/default_profile.png
--------------------------------------------------------------------------------
/src/assets/chat_notification.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msobkyy/backbook/HEAD/src/assets/chat_notification.wav
--------------------------------------------------------------------------------
/src/assets/notification_sweet.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msobkyy/backbook/HEAD/src/assets/notification_sweet.wav
--------------------------------------------------------------------------------
/public/images/postBackgrounds/1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msobkyy/backbook/HEAD/public/images/postBackgrounds/1.jpg
--------------------------------------------------------------------------------
/public/images/postBackgrounds/2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msobkyy/backbook/HEAD/public/images/postBackgrounds/2.jpg
--------------------------------------------------------------------------------
/public/images/postBackgrounds/3.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msobkyy/backbook/HEAD/public/images/postBackgrounds/3.jpg
--------------------------------------------------------------------------------
/public/images/postBackgrounds/4.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msobkyy/backbook/HEAD/public/images/postBackgrounds/4.jpg
--------------------------------------------------------------------------------
/public/images/postBackgrounds/5.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msobkyy/backbook/HEAD/public/images/postBackgrounds/5.jpg
--------------------------------------------------------------------------------
/public/images/postBackgrounds/6.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msobkyy/backbook/HEAD/public/images/postBackgrounds/6.jpg
--------------------------------------------------------------------------------
/public/images/postBackgrounds/7.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msobkyy/backbook/HEAD/public/images/postBackgrounds/7.jpg
--------------------------------------------------------------------------------
/public/images/postBackgrounds/8.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msobkyy/backbook/HEAD/public/images/postBackgrounds/8.jpg
--------------------------------------------------------------------------------
/public/images/postBackgrounds/9.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msobkyy/backbook/HEAD/public/images/postBackgrounds/9.jpg
--------------------------------------------------------------------------------
/public/images/postBackgrounds/10.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msobkyy/backbook/HEAD/public/images/postBackgrounds/10.jpg
--------------------------------------------------------------------------------
/src/components/UI/Card/Card.module.css:
--------------------------------------------------------------------------------
1 | .card {
2 | background: var(--bg-primary);
3 | border-radius: 10px;
4 | box-shadow: 0 2px 4px var(--shadow-1);
5 | padding: 1rem;
6 | }
7 |
--------------------------------------------------------------------------------
/src/pages/forgot/style.module.css:
--------------------------------------------------------------------------------
1 | .wrapper {
2 | background: var(--bg-secondary);
3 | height: 78vh;
4 | min-height: 600px;
5 | display: flex;
6 | justify-content: center;
7 | align-items: center;
8 | padding: 10px;
9 | }
10 |
--------------------------------------------------------------------------------
/src/components/UI/Loading/Loading.module.css:
--------------------------------------------------------------------------------
1 | .main {
2 | height: 100vh;
3 | width: 100%;
4 | color: var(--color-primary);
5 | background: var(--bg-primary);
6 | display: flex;
7 | align-items: center;
8 | justify-content: center;
9 | }
10 |
--------------------------------------------------------------------------------
/src/utils/Portal.js:
--------------------------------------------------------------------------------
1 | import { createPortal } from "react-dom";
2 |
3 | function Portal({ children, id }) {
4 | const portalDom = id ? document.getElementById(id) : document.body;
5 |
6 | return createPortal(children, portalDom);
7 | }
8 |
9 | export default Portal;
10 |
--------------------------------------------------------------------------------
/src/pages/post/style.module.css:
--------------------------------------------------------------------------------
1 | .post {
2 | display: flex;
3 | flex-direction: column;
4 | align-items: center;
5 | justify-content: center;
6 | width: 100%;
7 | height: 100%;
8 | background: var(--bg-secondary);
9 | padding: 70px 6px;
10 | }
11 | .container {
12 | width: 100%;
13 | max-width: 590px;
14 | }
15 |
--------------------------------------------------------------------------------
/src/components/UI/Error/ErrorPage.module.css:
--------------------------------------------------------------------------------
1 | .main {
2 | height: calc(100vh - 100px);
3 | width: 100%;
4 | color: var(--color-primary);
5 | background: var(--bg-secondary);
6 | display: flex;
7 | align-items: center;
8 | justify-content: center;
9 | flex-direction: column;
10 | gap: 20px;
11 | font-size: 24px;
12 | }
13 |
--------------------------------------------------------------------------------
/src/components/UI/Card/Card.jsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import styles from "./Card.module.css";
3 |
4 | function Card({ children, className, innerRef, style }) {
5 | return (
6 |
7 | {children}
8 |
9 | );
10 | }
11 |
12 | export default Card;
13 |
--------------------------------------------------------------------------------
/src/components/UI/Loading/Loading.jsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import classes from "./Loading.module.css";
3 | import PuffLoader from "react-spinners/PuffLoader";
4 |
5 | function Loading() {
6 | return (
7 |
10 | );
11 | }
12 |
13 | export default Loading;
14 |
--------------------------------------------------------------------------------
/src/components/home/left/Shortcut.jsx:
--------------------------------------------------------------------------------
1 | import styles from "./HomeLeft.module.css";
2 |
3 | export default function Shortcut({ link, img, name }) {
4 | return (
5 |
11 |
12 | {name}
13 |
14 | );
15 | }
16 |
--------------------------------------------------------------------------------
/src/utils/isRTL.js:
--------------------------------------------------------------------------------
1 | export default function isRTL(s) {
2 | const ltrChars =
3 | "A-Za-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02B8\u0300-\u0590\u0800-\u1FFF" +
4 | "\u2C00-\uFB1C\uFDFE-\uFE6F\uFEFD-\uFFFF";
5 | const rtlChars = "\u0591-\u07FF\uFB1D-\uFDFD\uFE70-\uFEFC";
6 | const rtlDirCheck = new RegExp("^[^" + ltrChars + "]*[" + rtlChars + "]");
7 |
8 | return rtlDirCheck.test(s);
9 | }
10 |
--------------------------------------------------------------------------------
/src/app/store.js:
--------------------------------------------------------------------------------
1 | import { configureStore } from "@reduxjs/toolkit";
2 | import userSlice from "./slices/userSlice";
3 | import createPostSlice from "./slices/createPostSlice";
4 | import createSoketSlice from "./slices/soketSlice";
5 |
6 | export const store = configureStore({
7 | reducer: {
8 | user: userSlice,
9 | createPost: createPostSlice,
10 | soketSlice: createSoketSlice,
11 | },
12 | });
13 |
--------------------------------------------------------------------------------
/src/routes/NotLoggedIn.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 |
3 | import { Navigate, Outlet } from "react-router-dom";
4 | import Loading from "../components/UI/Loading/Loading";
5 |
6 | export default function NotLoggedIn({ user }) {
7 | return user.userinfo ? (
8 |
9 | ) : (
10 | }>
11 |
12 |
13 | );
14 | }
15 |
--------------------------------------------------------------------------------
/src/svg/arrowDown.js:
--------------------------------------------------------------------------------
1 | function ArrowDown({ color }) {
2 | return (
3 |
6 | );
7 | }
8 |
9 | export default ArrowDown;
10 |
--------------------------------------------------------------------------------
/src/components/home/right/Contact.jsx:
--------------------------------------------------------------------------------
1 | import styles from "./HomeRight.module.css";
2 |
3 | export default function Contact({ user }) {
4 | return (
5 |
6 |
7 |

8 |
9 |
10 | {user.first_name} {user.last_name}
11 |
12 |
13 | );
14 | }
15 |
--------------------------------------------------------------------------------
/.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 | *.env
8 |
9 | # testing
10 | /coverage
11 |
12 | # production
13 | /build
14 |
15 | # misc
16 | .DS_Store
17 | .env.local
18 | .env.development.local
19 | .env.test.local
20 | .env.production.local
21 |
22 | npm-debug.log*
23 | yarn-debug.log*
24 | yarn-error.log*
25 |
--------------------------------------------------------------------------------
/src/components/header/AllMenuItem.jsx:
--------------------------------------------------------------------------------
1 | import styles from "./AllMenu.module.css";
2 |
3 | export default function AllMenuItem({ name, description, icon }) {
4 | return (
5 |
6 |

7 |
8 | {name}
9 | {description}
10 |
11 |
12 | );
13 | }
14 |
--------------------------------------------------------------------------------
/src/svg/dots.js:
--------------------------------------------------------------------------------
1 | function Dots({ color }) {
2 | return (
3 |
10 | );
11 | }
12 |
13 | export default Dots;
14 |
--------------------------------------------------------------------------------
/src/components/noAuthHeader/style.module.css:
--------------------------------------------------------------------------------
1 | .header {
2 | position: fixed;
3 | top: 0;
4 | left: 0;
5 | height: 56px;
6 | z-index: 99;
7 | background: var(--bg-primary);
8 | width: 100%;
9 | box-shadow: 0 2px 4px var(--shadow-1);
10 | display: flex;
11 | justify-content: space-between;
12 | padding: 10px 25px;
13 | align-items: center;
14 | color: var(--color-primary);
15 | }
16 | .login button {
17 | height: auto;
18 | font-weight: 500;
19 | }
20 |
--------------------------------------------------------------------------------
/src/svg/arrowDow1.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 |
3 | function ArrowDown1({ color }) {
4 | return (
5 |
12 | );
13 | }
14 |
15 | export default ArrowDown1;
16 |
--------------------------------------------------------------------------------
/src/components/posts/post/MenuItem.jsx:
--------------------------------------------------------------------------------
1 | import classes from "./Post.module.css";
2 |
3 | export default function MenuItem({ icon, title, subtitle, img }) {
4 | return (
5 |
6 | {img ?
: }
7 |
8 | {title}
9 | {subtitle && {subtitle}}
10 |
11 |
12 | );
13 | }
14 |
--------------------------------------------------------------------------------
/src/components/home/stories/Story.jsx:
--------------------------------------------------------------------------------
1 | import styles from "./Stories.module.css";
2 |
3 | export default function Story({ story }) {
4 | return (
5 |
6 |

7 |
8 |

9 |
10 |
{story.profile_name}
11 |
12 | );
13 | }
14 |
--------------------------------------------------------------------------------
/src/components/messages/chatInfo/chatInfo.module.css:
--------------------------------------------------------------------------------
1 | .main {
2 | display: flex;
3 | justify-content: space-between;
4 | align-items: center;
5 | padding: 10px;
6 | border-radius: 8px;
7 | cursor: pointer;
8 | font-size: 14px;
9 | font-weight: 600;
10 | }
11 | .rotate360 {
12 | transform: rotate(180deg);
13 | }
14 | .content {
15 | padding: 5px;
16 | max-height: 320px;
17 | overflow: auto;
18 | }
19 |
20 | :global(.dark) .icon svg {
21 | fill: rgb(144, 144, 144);
22 | }
23 |
--------------------------------------------------------------------------------
/src/data/post.js:
--------------------------------------------------------------------------------
1 | export const postBackgrounds = [
2 | "../../images/postBackgrounds/1.jpg",
3 | "../../images/postBackgrounds/2.jpg",
4 | "../../images/postBackgrounds/3.jpg",
5 | "../../images/postBackgrounds/4.jpg",
6 | "../../images/postBackgrounds/5.jpg",
7 | "../../images/postBackgrounds/6.jpg",
8 | "../../images/postBackgrounds/7.jpg",
9 | "../../images/postBackgrounds/8.jpg",
10 | "../../images/postBackgrounds/9.jpg",
11 | "../../images/postBackgrounds/10.jpg",
12 | ];
13 |
--------------------------------------------------------------------------------
/src/utils/radialToLinearGradient.js:
--------------------------------------------------------------------------------
1 | export default function radialToLinearGradient(radialGradient) {
2 | var linearGradient = "linear-gradient(";
3 | var colorsAndPositions = radialGradient.match(/rgb\(\d+, \d+, \d+\)/g);
4 | for (var i = 0; i < colorsAndPositions.length; i++) {
5 | linearGradient += colorsAndPositions[i];
6 | if (i < colorsAndPositions.length - 1) {
7 | linearGradient += ", ";
8 | }
9 | }
10 | linearGradient += ")";
11 | return linearGradient;
12 | }
13 |
--------------------------------------------------------------------------------
/src/styles/dark.css:
--------------------------------------------------------------------------------
1 | .dark {
2 | --bg-primary: #242526;
3 | --bg-secondary: #18191a;
4 | --bg-third: #3a3b3c;
5 | --bg-forth: #3a3b3c;
6 | --bg-fifth: #888888;
7 | --color-primary: #e4e6eb;
8 | --color-secondary: #b0b3b8;
9 | --divider: #4e4e4e;
10 | --light-blue-color: rgba(45, 136, 255, 0.1);
11 | }
12 | .dark .blur {
13 | background: rgba(1, 1, 1, 0.53);
14 | }
15 | .dark .small_circle i {
16 | filter: invert(100%);
17 | }
18 |
19 | .dark .create_icon {
20 | filter: invert(100%);
21 | }
22 |
--------------------------------------------------------------------------------
/src/hooks/useSearch.js:
--------------------------------------------------------------------------------
1 | import { useMutation } from "@tanstack/react-query";
2 | import axios from "axios";
3 |
4 | const Search = async ({ term }) => {
5 | const { data } = await axios.post(
6 | `${process.env.REACT_APP_BACKEND_URL}/api/v1/users/search`,
7 | { term },
8 | {
9 | withCredentials: true,
10 | }
11 | );
12 | return data;
13 | };
14 |
15 | export const useSearch = () => {
16 | return useMutation({
17 | mutationKey: "useSearch",
18 | mutationFn: Search,
19 | });
20 | };
21 |
--------------------------------------------------------------------------------
/src/svg/gaming.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | function Gaming({ color }) {
4 | return (
5 |
8 | );
9 | }
10 |
11 | export default Gaming;
12 |
--------------------------------------------------------------------------------
/src/hooks/useGetChat.js:
--------------------------------------------------------------------------------
1 | import { useMutation } from "@tanstack/react-query";
2 | import axios from "axios";
3 |
4 | const GetChat = async ({ user }) => {
5 | const { data } = await axios.post(
6 | `${process.env.REACT_APP_BACKEND_URL}/api/v1/chats/create/private`,
7 | { userId: user },
8 | {
9 | withCredentials: true,
10 | }
11 | );
12 | return data;
13 | };
14 |
15 | export const useGetChat = () => {
16 | return useMutation({
17 | mutationKey: "useGetChat",
18 | mutationFn: GetChat,
19 | });
20 | };
21 |
--------------------------------------------------------------------------------
/src/hooks/useDeletePost.js:
--------------------------------------------------------------------------------
1 | import { useMutation } from "@tanstack/react-query";
2 | import axios from "axios";
3 |
4 | const DeletePost = async ({ post }) => {
5 | const { data } = await axios.put(
6 | `${process.env.REACT_APP_BACKEND_URL}/api/v1/posts/${post}`,
7 | {},
8 | {
9 | withCredentials: true,
10 | }
11 | );
12 | return data;
13 | };
14 |
15 | export const useDeletePost = (post) => {
16 | return useMutation({
17 | mutationKey: ["useDeletePost", post],
18 | mutationFn: DeletePost,
19 | });
20 | };
21 |
--------------------------------------------------------------------------------
/src/svg/unseen.js:
--------------------------------------------------------------------------------
1 | function UnSeen({ color = "#ffffff4d" }) {
2 | return (
3 |
14 | );
15 | }
16 |
17 | export default UnSeen;
18 |
--------------------------------------------------------------------------------
/src/hooks/useAddToSearch.js:
--------------------------------------------------------------------------------
1 | import { useMutation } from "@tanstack/react-query";
2 | import axios from "axios";
3 |
4 | const AddToSearch = async ({ user }) => {
5 | const { data } = await axios.post(
6 | `${process.env.REACT_APP_BACKEND_URL}/api/v1/users/search/add`,
7 | { searchUser: user },
8 | {
9 | withCredentials: true,
10 | }
11 | );
12 | return data;
13 | };
14 |
15 | export const useAddToSearch = () => {
16 | return useMutation({
17 | mutationKey: "useAddToSearch",
18 | mutationFn: AddToSearch,
19 | });
20 | };
21 |
--------------------------------------------------------------------------------
/src/fcm.js:
--------------------------------------------------------------------------------
1 | import { initializeApp } from "firebase/app";
2 | import { getMessaging } from "firebase/messaging";
3 |
4 | const firebaseConfig = {
5 | apiKey: "AIzaSyD8bk57MfPgPmzRQU6fA2x89AZ4ldQlS80",
6 | authDomain: "backbook-370316.firebaseapp.com",
7 | projectId: "backbook-370316",
8 | storageBucket: "backbook-370316.appspot.com",
9 | messagingSenderId: "398150721140",
10 | appId: "1:398150721140:web:d93f0193496929a5037b21",
11 | measurementId: "G-VVEDB7NXXQ",
12 | };
13 |
14 | export const app = initializeApp(firebaseConfig);
15 | export const messaging = getMessaging(app);
16 |
--------------------------------------------------------------------------------
/src/hooks/useRemoveFromSearch.js:
--------------------------------------------------------------------------------
1 | import { useMutation } from "@tanstack/react-query";
2 | import axios from "axios";
3 |
4 | const RemoveFromSearch = async ({ user }) => {
5 | const { data } = await axios.post(
6 | `${process.env.REACT_APP_BACKEND_URL}/api/v1/users/search/remove`,
7 | { searchUser: user },
8 | {
9 | withCredentials: true,
10 | }
11 | );
12 | return data;
13 | };
14 |
15 | export const useRemoveFromSearch = () => {
16 | return useMutation({
17 | mutationKey: "useRemoveFromSearch",
18 | mutationFn: RemoveFromSearch,
19 | });
20 | };
21 |
--------------------------------------------------------------------------------
/src/components/home/left/LeftLink.jsx:
--------------------------------------------------------------------------------
1 | import styles from "./HomeLeft.module.css";
2 |
3 | export default function LeftLink({ img, text, notification }) {
4 | return (
5 |
6 |

7 | {notification !== undefined ? (
8 |
9 |
{text}
10 |
{notification}
11 |
12 | ) : (
13 |
{text}
14 | )}
15 |
16 | );
17 | }
18 |
--------------------------------------------------------------------------------
/src/components/input/login/input.module.css:
--------------------------------------------------------------------------------
1 | .wrap {
2 | width: 100%;
3 | position: relative;
4 | }
5 | .wrap input {
6 | background: var(--bg-primary);
7 | border: 1px solid var(--bg-third);
8 | border-radius: 10px;
9 | color: var(--color-primary);
10 | font-size: 17px;
11 | height: 50px;
12 | margin-bottom: 10px;
13 | outline: none;
14 | padding-left: 10px;
15 | width: 100%;
16 | }
17 | .error {
18 | border-color: #b94a48 !important;
19 | }
20 | .wrap i {
21 | position: absolute;
22 | right: 5px;
23 | top: 15px;
24 | -webkit-transform: scale(0.8);
25 | transform: scale(0.8);
26 | }
27 |
--------------------------------------------------------------------------------
/src/components/input/signup/style.module.css:
--------------------------------------------------------------------------------
1 | .wrap {
2 | width: 100%;
3 | position: relative;
4 | }
5 | .wrap input {
6 | background: var(--bg-secondary);
7 | border: 1px solid var(--bg-third);
8 | border-radius: 10px;
9 | color: var(--color-primary);
10 | font-size: 17px;
11 | height: 50px;
12 | margin-bottom: 10px;
13 | outline: none;
14 | padding-left: 10px;
15 | width: 100%;
16 | }
17 | .error {
18 | border-color: #b94a48 !important;
19 | }
20 | .wrap i {
21 | position: absolute;
22 | right: 5px;
23 | top: 15px;
24 | -webkit-transform: scale(0.8);
25 | transform: scale(0.8);
26 | }
27 |
--------------------------------------------------------------------------------
/src/components/ActivateAccount/ActivateAccount.module.css:
--------------------------------------------------------------------------------
1 | .card {
2 | min-width: 400px;
3 | display: flex;
4 | flex-direction: column;
5 | justify-content: center;
6 | position: absolute;
7 | left: 50%;
8 | top: 50%;
9 | -webkit-transform: translate(-50%, -50%);
10 | transform: translate(-50%, -50%);
11 | }
12 |
13 | .header {
14 | width: 100%;
15 | padding: 8px 5px;
16 | text-align: center;
17 | }
18 | .body {
19 | display: flex;
20 | align-items: center;
21 | justify-content: center;
22 | padding: 10px;
23 | }
24 | @media (max-width: 400px) {
25 | .card {
26 | min-width: 95%;
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/src/svg/plus.js:
--------------------------------------------------------------------------------
1 | function Plus({ color }) {
2 | return (
3 |
15 | );
16 | }
17 |
18 | export default Plus;
19 |
--------------------------------------------------------------------------------
/src/svg/watch.js:
--------------------------------------------------------------------------------
1 | function Watch({ color }) {
2 | return (
3 |
6 | );
7 | }
8 |
9 | export default Watch;
10 |
--------------------------------------------------------------------------------
/src/utils/useOnClickOutside.js:
--------------------------------------------------------------------------------
1 | import { useEffect } from "react";
2 |
3 | export default function useOnClickOutside(ref, handler) {
4 | useEffect(() => {
5 | const listener = (event) => {
6 | if (!ref.current || ref.current.contains(event.target)) {
7 | return;
8 | }
9 | handler(event);
10 | };
11 | document.addEventListener("mousedown", listener);
12 | document.addEventListener("touchstart", listener);
13 | return () => {
14 | document.removeEventListener("mousedown", listener);
15 | document.removeEventListener("touchstart", listener);
16 | };
17 | }, [ref, handler]);
18 | }
19 |
--------------------------------------------------------------------------------
/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "React App",
3 | "name": "Create React App Sample",
4 | "icons": [
5 | {
6 | "src": "icons/backbook-icon.ico",
7 | "sizes": "64x64 32x32 24x24 16x16",
8 | "type": "image/x-icon"
9 | },
10 | {
11 | "src": "icons/backbook-icon.png",
12 | "type": "image/png",
13 | "sizes": "192x192"
14 | },
15 | {
16 | "src": "icons/backbook-icon.png",
17 | "type": "image/png",
18 | "sizes": "512x512"
19 | }
20 | ],
21 | "start_url": ".",
22 | "display": "standalone",
23 | "theme_color": "#000000",
24 | "background_color": "#ffffff"
25 | }
26 |
--------------------------------------------------------------------------------
/src/components/noAuthHeader/index.jsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import styles from "./style.module.css";
3 | import { Link } from "react-router-dom";
4 | import { Logo } from "../../svg";
5 |
6 | function NoAuthHeader() {
7 | return (
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 | );
19 | }
20 |
21 | export default NoAuthHeader;
22 |
--------------------------------------------------------------------------------
/src/svg/menu.js:
--------------------------------------------------------------------------------
1 | function Menu() {
2 | return (
3 |
14 | );
15 | }
16 |
17 | export default Menu;
18 |
--------------------------------------------------------------------------------
/src/svg/homeActive.js:
--------------------------------------------------------------------------------
1 | function HomeActive({ className }) {
2 | return (
3 |
12 | );
13 | }
14 |
15 | export default HomeActive;
16 |
--------------------------------------------------------------------------------
/src/utils/messagesPosition.js:
--------------------------------------------------------------------------------
1 | export function isSameUser(msg, user) {
2 | return msg.sender._id !== user._id;
3 | }
4 |
5 | export function isLastMsg(msg, msgs, i) {
6 | return (
7 | msg.sender._id !== msgs[i - 1]?.sender._id &&
8 | msg.sender._id === msgs[i + 1]?.sender._id
9 | );
10 | }
11 |
12 | export function isFirstMsg(msg, msgs, i) {
13 | return (
14 | msg.sender._id !== msgs[i + 1]?.sender._id &&
15 | msg.sender._id === msgs[i - 1]?.sender._id
16 | );
17 | }
18 | export function isSingleMsg(msg, msgs, i) {
19 | return (
20 | msg.sender._id !== msgs[i + 1]?.sender._id &&
21 | msg.sender._id !== msgs[i - 1]?.sender._id
22 | );
23 | }
24 |
--------------------------------------------------------------------------------
/src/svg/messenger.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | function Messenger() {
4 | return (
5 |
8 | );
9 | }
10 |
11 | export default Messenger;
12 |
--------------------------------------------------------------------------------
/src/hooks/useAddFCM.js:
--------------------------------------------------------------------------------
1 | import { useMutation } from "@tanstack/react-query";
2 | import axios from "axios";
3 | import Cookies from "js-cookie";
4 |
5 | const AddFCM = async ({ fcm }) => {
6 | const { data } = await axios.post(
7 | `${process.env.REACT_APP_BACKEND_URL}/api/v1/users/fcm`,
8 | { fcmToken: fcm },
9 | {
10 | withCredentials: true,
11 | }
12 | );
13 | return data;
14 | };
15 |
16 | export const useAddFCM = () => {
17 | return useMutation({
18 | mutationKey: "useAddFCM",
19 | mutationFn: AddFCM,
20 | onSuccess: (data) => {
21 | Cookies.set("fcm", JSON.stringify(data.fcmToken), {
22 | expires: 90,
23 | });
24 | },
25 | });
26 | };
27 |
--------------------------------------------------------------------------------
/src/svg/notifications.js:
--------------------------------------------------------------------------------
1 | function Notifications() {
2 | return (
3 |
6 | );
7 | }
8 |
9 | export default Notifications;
10 |
--------------------------------------------------------------------------------
/src/hooks/useOnClickOutside.js:
--------------------------------------------------------------------------------
1 | import { useEffect } from "react";
2 |
3 | export default function useOnClickOutside(ref, state, handler) {
4 | useEffect(() => {
5 | const listener = (event) => {
6 | if (
7 | !ref.current ||
8 | ref.current.contains(event.target) ||
9 | state === false
10 | ) {
11 | return;
12 | }
13 | handler(event);
14 | };
15 | document.addEventListener("mousedown", listener);
16 | document.addEventListener("touchstart", listener);
17 | return () => {
18 | document.removeEventListener("mousedown", listener);
19 | document.removeEventListener("touchstart", listener);
20 | };
21 | }, [ref, handler, state]);
22 | }
23 |
--------------------------------------------------------------------------------
/src/hooks/useWindowDimensions .js:
--------------------------------------------------------------------------------
1 | import { useState, useEffect } from "react";
2 |
3 | function getWindowDimensions() {
4 | const { innerWidth: width, innerHeight: height } = window;
5 | return {
6 | width,
7 | height,
8 | };
9 | }
10 |
11 | export default function useWindowDimensions() {
12 | const [windowDimensions, setWindowDimensions] = useState(
13 | getWindowDimensions()
14 | );
15 |
16 | useEffect(() => {
17 | function handleResize() {
18 | setWindowDimensions(getWindowDimensions());
19 | }
20 |
21 | window.addEventListener("resize", handleResize);
22 | return () => window.removeEventListener("resize", handleResize);
23 | }, []);
24 |
25 | return windowDimensions;
26 | }
27 |
--------------------------------------------------------------------------------
/src/svg/friendsActive.js:
--------------------------------------------------------------------------------
1 | function FriendsActive() {
2 | return (
3 |
6 | );
7 | }
8 |
9 | export default FriendsActive;
10 |
--------------------------------------------------------------------------------
/src/svg/arrowRight.js:
--------------------------------------------------------------------------------
1 | function ArrowRight({ color }) {
2 | return (
3 |
15 | );
16 | }
17 |
18 | export default ArrowRight;
19 |
--------------------------------------------------------------------------------
/src/components/posts/post/likes/ReactsPopup.module.css:
--------------------------------------------------------------------------------
1 | .popup {
2 | display: flex;
3 | align-items: center;
4 | justify-content: center;
5 | background: var(--bg-primary);
6 | padding: 7px;
7 | border-radius: 50px;
8 | gap: 12px;
9 | border: 0.4px solid var(--divider);
10 | box-shadow: 0 0 2px 1px rgb(0 0 0 / 6%);
11 | }
12 | .react {
13 | display: flex;
14 | align-items: center;
15 | justify-content: center;
16 | background-color: white;
17 | border-radius: 100%;
18 | transform: scale(0.98);
19 | transition: transform 0.2s;
20 | }
21 |
22 | .react:hover {
23 | transform: scale(1.2) translateY(-10px);
24 | }
25 | .react img {
26 | width: 35px;
27 | height: 35px;
28 | cursor: pointer;
29 |
30 | transform: scale(1.2);
31 | }
32 |
--------------------------------------------------------------------------------
/src/svg/return.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | function Return({ color }) {
4 | return (
5 |
17 | );
18 | }
19 |
20 | export default Return;
21 |
--------------------------------------------------------------------------------
/src/pages/messages/SeenStatus.jsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import { UnSeen } from "../../svg";
3 | import styles from "./messages.module.css";
4 |
5 | function SeenStatus({ chat, user }) {
6 | return (
7 | <>
8 | {chat?.latestMessage?.sender._id === user._id ? (
9 | chat?.latestMessage?.seen === "seen" ? (
10 |
11 | ) : (
12 |
13 |
14 |
15 | )
16 | ) : chat?.latestMessage?.seen === "unseen" ? (
17 |
18 | ) : (
19 | ""
20 | )}
21 | >
22 | );
23 | }
24 |
25 | export default SeenStatus;
26 |
--------------------------------------------------------------------------------
/src/svg/newRoom.js:
--------------------------------------------------------------------------------
1 | function NewRoom({ color }) {
2 | return (
3 |
10 | );
11 | }
12 |
13 | export default NewRoom;
14 |
--------------------------------------------------------------------------------
/src/components/messages/chatInfo/chatInfo.jsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import { useState } from "react";
3 | import { ArrowDown1 } from "../../../svg";
4 | import styles from "./chatInfo.module.css";
5 |
6 | function ChatInfo({ title, children }) {
7 | const [show, setShow] = useState(false);
8 | return (
9 | <>
10 | {
13 | setShow((prev) => !prev);
14 | }}
15 | >
16 |
{title}
17 |
20 |
21 | {show && {children}
}
22 | >
23 | );
24 | }
25 |
26 | export default ChatInfo;
27 |
--------------------------------------------------------------------------------
/src/pages/profile/ProfileMenu.jsx:
--------------------------------------------------------------------------------
1 | import { Link } from "react-router-dom";
2 | import { Dots } from "../../svg";
3 | import classes from "./style.module.css";
4 |
5 | export default function ProfileMenu() {
6 | return (
7 |
8 |
9 |
10 | Posts
11 |
12 |
13 | About
14 |
15 |
16 | Friends
17 |
18 |
19 | Photos
20 |
21 |
22 |
23 |
24 |
25 |
26 | );
27 | }
28 |
--------------------------------------------------------------------------------
/src/hooks/useReaction.js:
--------------------------------------------------------------------------------
1 | import { useMutation } from "@tanstack/react-query";
2 | import axios from "axios";
3 | import { socket } from "../routes/IsLoggedIn";
4 |
5 | const AddReact = async ({ post, type }) => {
6 | const { data } = await axios.put(
7 | `${process.env.REACT_APP_BACKEND_URL}/api/v1/posts/${post}/reacts`,
8 | { type },
9 | {
10 | withCredentials: true,
11 | }
12 | );
13 | return data;
14 | };
15 |
16 | export const useReaction = () => {
17 | return useMutation({
18 | mutationKey: "useReaction",
19 | mutationFn: AddReact,
20 | onSuccess: (data) => {
21 | const newNotification = data?.data?.newNotification;
22 | if (newNotification) {
23 | socket.emit("notification", { notification: newNotification });
24 | }
25 | },
26 | });
27 | };
28 |
--------------------------------------------------------------------------------
/src/pages/login/index.jsx:
--------------------------------------------------------------------------------
1 | import { useState } from "react";
2 | import LoginForm from "../../components/login/LoginForm";
3 | import LoginFooter from "../../components/login/LoginFooter";
4 | import styles from "./style.module.css";
5 | import SignupForm from "../../components/login/SignupForm";
6 |
7 | function Login() {
8 | const [renderSignUp, setRenderSignUp] = useState(false);
9 | return (
10 |
11 |
12 |
13 | {renderSignUp && (
14 |
18 | )}
19 |
20 |
21 |
22 | );
23 | }
24 |
25 | export default Login;
26 |
--------------------------------------------------------------------------------
/src/hooks/useCommentLike.js:
--------------------------------------------------------------------------------
1 | import { useMutation } from "@tanstack/react-query";
2 | import axios from "axios";
3 | import { socket } from "../routes/IsLoggedIn";
4 |
5 | const AddCommentLike = async ({ comment }) => {
6 | const { data } = await axios.put(
7 | `${process.env.REACT_APP_BACKEND_URL}/api/v1/posts/comments/${comment}/like`,
8 | {},
9 | {
10 | withCredentials: true,
11 | }
12 | );
13 | return data;
14 | };
15 |
16 | export const useCommentLike = (comment) => {
17 | return useMutation({
18 | mutationKey: ["useCommentLike", comment],
19 | mutationFn: AddCommentLike,
20 | onSuccess: (data) => {
21 | const newNotification = data?.data?.newNotification;
22 | if (newNotification) {
23 | socket.emit("notification", { notification: newNotification });
24 | }
25 | },
26 | });
27 | };
28 |
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import * as ReactDOMClient from "react-dom/client";
3 | import "./index.css";
4 | import "./styles/dark.css";
5 | import "react-loading-skeleton/dist/skeleton.css";
6 |
7 | import "./styles/icons/icons.css";
8 | import App from "./App";
9 | import { BrowserRouter } from "react-router-dom";
10 | import { Provider } from "react-redux";
11 | import { store } from "./app/store";
12 | import axios from "axios";
13 | import Cookies from "js-cookie";
14 |
15 | const token = Cookies.get("token") ? JSON.parse(Cookies.get("token")) : null;
16 |
17 | if (token) axios.defaults.headers.common["Authorization"] = `Bearer ${token}`;
18 |
19 | const root = ReactDOMClient.createRoot(document.getElementById("backbook"));
20 | root.render(
21 |
22 |
23 |
24 |
25 |
26 | );
27 |
--------------------------------------------------------------------------------
/src/svg/info.js:
--------------------------------------------------------------------------------
1 | function Info({ color = "#0096ff" }) {
2 | return (
3 |
19 | );
20 | }
21 |
22 | export default Info;
23 |
--------------------------------------------------------------------------------
/src/utils/dataURItoBlob.js:
--------------------------------------------------------------------------------
1 | export default function dataURItoBlob(dataURI) {
2 | // convert base64 to raw binary data held in a string
3 | // doesn't handle URLEncoded DataURIs - see SO answer #6850276 for code that does this
4 | var byteString = atob(dataURI.split(",")[1]);
5 |
6 | // separate out the mime component
7 | var mimeString = dataURI.split(",")[0].split(":")[1].split(";")[0];
8 |
9 | // write the bytes of the string to an ArrayBuffer
10 | var ab = new ArrayBuffer(byteString.length);
11 |
12 | // create a view into the buffer
13 | var ia = new Uint8Array(ab);
14 |
15 | // set the bytes of the buffer to the correct values
16 | for (var i = 0; i < byteString.length; i++) {
17 | ia[i] = byteString.charCodeAt(i);
18 | }
19 |
20 | // write the ArrayBuffer to a blob, and you're done
21 | var blob = new Blob([ab], { type: mimeString });
22 | return blob;
23 | }
24 |
--------------------------------------------------------------------------------
/src/svg/home.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 |
3 | function Home({ color, className }) {
4 | return (
5 |
14 | );
15 | }
16 |
17 | export default Home;
18 |
--------------------------------------------------------------------------------
/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
10 |
11 |
15 |
16 |
17 |
21 | Backbook
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/src/components/header/userMenu/HelpSupport.jsx:
--------------------------------------------------------------------------------
1 | import styles from "./UserMenu.module.css";
2 | import { user_menu2 } from "../../..//data/allMenu";
3 |
4 | export default function HelpSupport({ setVisible }) {
5 | return (
6 |
7 |
8 |
{
11 | setVisible(0);
12 | }}
13 | >
14 |
15 |
16 | Settings & privacy
17 |
18 | {user_menu2.map(({ name, icon }) => (
19 |
20 |
21 |
22 |
23 |
{name}
24 |
25 | ))}
26 |
27 | );
28 | }
29 |
--------------------------------------------------------------------------------
/src/svg/like.js:
--------------------------------------------------------------------------------
1 | function Like({ color = "#0096ff", height = "20", width = "20", style }) {
2 | return (
3 |
14 | );
15 | }
16 |
17 | export default Like;
18 |
--------------------------------------------------------------------------------
/src/components/header/userMenu/SettingsPrivacy.jsx:
--------------------------------------------------------------------------------
1 | import styles from "./UserMenu.module.css";
2 | import { user_menu1 } from "../../..//data/allMenu";
3 |
4 | export default function SettingsPrivacy({ setVisible }) {
5 | return (
6 |
7 |
8 |
{
11 | setVisible(0);
12 | }}
13 | >
14 |
15 |
16 | Settings & privacy
17 |
18 | {user_menu1.map(({ name, icon }, i) => (
19 |
20 |
21 |
22 |
23 |
{name}
24 |
25 | ))}
26 |
27 | );
28 | }
29 |
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "git.enabled": true,
3 | "workbench.colorCustomizations": {
4 | "activityBar.activeBackground": "#93e6fc",
5 | "activityBar.background": "#93e6fc",
6 | "activityBar.foreground": "#15202b",
7 | "activityBar.inactiveForeground": "#15202b99",
8 | "activityBarBadge.background": "#fa45d4",
9 | "activityBarBadge.foreground": "#15202b",
10 | "commandCenter.border": "#15202b99",
11 | "sash.hoverBorder": "#93e6fc",
12 | "statusBar.background": "#61dafb",
13 | "statusBar.foreground": "#15202b",
14 | "statusBarItem.hoverBackground": "#2fcefa",
15 | "statusBarItem.remoteBackground": "#61dafb",
16 | "statusBarItem.remoteForeground": "#15202b",
17 | "titleBar.activeBackground": "#61dafb",
18 | "titleBar.activeForeground": "#15202b",
19 | "titleBar.inactiveBackground": "#61dafb99",
20 | "titleBar.inactiveForeground": "#15202b99"
21 | },
22 | "peacock.color": "#61dafb"
23 | }
24 |
--------------------------------------------------------------------------------
/src/components/UI/Error/ErrorPage.jsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import classes from "./ErrorPage.module.css";
3 | import e404Animation from "../../UI/Lottie/404.json";
4 | import Lottie from "react-lottie-player";
5 | import { useNavigate } from "react-router-dom";
6 |
7 | function ErrorPage({ error }) {
8 | const navigate = useNavigate();
9 |
10 | return (
11 |
12 |
22 |
Something Went Wrong
23 |
{
27 | navigate("/");
28 | }}
29 | >
30 | Go to home
31 |
32 |
33 | );
34 | }
35 |
36 | export default ErrorPage;
37 |
--------------------------------------------------------------------------------
/public/firebase-messaging-sw.js:
--------------------------------------------------------------------------------
1 | importScripts("https://www.gstatic.com/firebasejs/8.10.0/firebase-app.js");
2 | importScripts(
3 | "https://www.gstatic.com/firebasejs/8.10.0/firebase-messaging.js"
4 | );
5 |
6 | const firebaseConfig = {
7 | apiKey: "AIzaSyD8bk57MfPgPmzRQU6fA2x89AZ4ldQlS80",
8 | projectId: "backbook-370316",
9 | messagingSenderId: "398150721140",
10 | appId: "1:398150721140:web:d93f0193496929a5037b21",
11 | };
12 |
13 | firebase.initializeApp(firebaseConfig);
14 | const messaging = firebase.messaging();
15 |
16 | messaging.onBackgroundMessage((payload) => {
17 | console.log(
18 | "[firebase-messaging-sw.js] Received background message ",
19 | payload
20 | );
21 | const notificationTitle = payload.notification.title;
22 | const notificationOptions = {
23 | body: payload.notification.body,
24 | icon: payload.notification.image,
25 | };
26 |
27 | // self.registration.showNotification(notificationTitle, notificationOptions);
28 | });
29 |
--------------------------------------------------------------------------------
/src/components/login/LoginFooter.module.css:
--------------------------------------------------------------------------------
1 | .footer {
2 | background: var(--bg-primary);
3 | padding: 1.5rem;
4 | }
5 | .warp {
6 | color: var(--color-secondary);
7 | display: flex;
8 | flex-wrap: wrap;
9 | font-size: 13px;
10 | gap: 3px 10px;
11 | margin: 0 auto;
12 | max-width: 350px;
13 | }
14 | .warp a {
15 | align-items: center;
16 | display: flex;
17 | }
18 | .warp a:hover {
19 | text-decoration: underline;
20 | }
21 | .footer div:nth-child(2) {
22 | margin: 1rem auto;
23 | max-width: 350px;
24 | }
25 | .square {
26 | align-items: center;
27 | background: var(--bg-secondary);
28 | border: 1px solid var(--bg-third);
29 | display: flex;
30 | height: 19px;
31 | justify-content: center;
32 | width: 30px;
33 | }
34 | @media (min-width: 539px) {
35 | .warp,
36 | .footer div:nth-child(2) {
37 | max-width: 520px;
38 | }
39 | }
40 | @media (min-width: 850px) {
41 | .warp,
42 | .footer div:nth-child(2) {
43 | max-width: 900px;
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/src/hooks/useComment.js:
--------------------------------------------------------------------------------
1 | import { useMutation } from "@tanstack/react-query";
2 | import axios from "axios";
3 | import { socket } from "../routes/IsLoggedIn";
4 |
5 | const AddComment = async ({ form, post, type }) => {
6 | const commentUrl = `${process.env.REACT_APP_BACKEND_URL}/api/v1/posts/AddComment/${post}`;
7 | const replyUrl = `${process.env.REACT_APP_BACKEND_URL}/api/v1/posts/comments/${post}/reply`;
8 |
9 | const { data } = await axios.post(
10 | type === "reply" ? replyUrl : commentUrl,
11 | form,
12 | {
13 | withCredentials: true,
14 | }
15 | );
16 | return data;
17 | };
18 |
19 | export const useComment = () => {
20 | return useMutation({
21 | mutationKey: "useComment",
22 | mutationFn: AddComment,
23 | onSuccess: (data) => {
24 | const newNotification = data?.data?.newNotification;
25 | if (newNotification) {
26 | socket.emit("notification", { notification: newNotification });
27 | }
28 | },
29 | });
30 | };
31 |
--------------------------------------------------------------------------------
/src/hooks/useCreateChatGroup.js:
--------------------------------------------------------------------------------
1 | import { useMutation } from "@tanstack/react-query";
2 | import axios from "axios";
3 | import { queryClient } from "../App";
4 |
5 | const CreateChatGroup = async ({ users, chatName }) => {
6 | const { data } = await axios.post(
7 | `${process.env.REACT_APP_BACKEND_URL}/api/v1/chats/create/group`,
8 | { users, chatName },
9 | {
10 | withCredentials: true,
11 | }
12 | );
13 | return data;
14 | };
15 |
16 | export const useCreateChatGroup = () => {
17 | return useMutation({
18 | mutationKey: "useCreateChatGroup",
19 | mutationFn: CreateChatGroup,
20 | onSuccess: (data) => {
21 | const newChat = data?.data?.chat;
22 |
23 | queryClient.setQueryData(["getChats"], (oldData) => {
24 | if (!oldData) return oldData;
25 | let newData = oldData;
26 | newData.data.chats = [newChat, ...newData.data.chats];
27 | return {
28 | ...oldData,
29 | newData,
30 | };
31 | });
32 | },
33 | });
34 | };
35 |
--------------------------------------------------------------------------------
/src/components/profile/cover/OldCovers.module.css:
--------------------------------------------------------------------------------
1 | .wrap {
2 | display: flex;
3 | align-items: center;
4 | justify-content: center;
5 | }
6 | .card {
7 | width: 100%;
8 | max-width: 700px;
9 | min-height: 70vh;
10 | padding: 0;
11 | margin: 8px;
12 | }
13 | .header {
14 | display: flex;
15 | align-items: center;
16 | justify-content: center;
17 | padding: 16px 0;
18 | border-bottom: 1px solid var(--divider);
19 | font-size: 20px;
20 | font-weight: 700;
21 | position: relative;
22 | }
23 | .header div {
24 | position: absolute;
25 | right: 0;
26 | }
27 | .content {
28 | padding: 16px;
29 | display: flex;
30 | flex-direction: column;
31 | gap: 16px;
32 | }
33 |
34 | .old_photos {
35 | display: flex;
36 | flex-wrap: wrap;
37 | gap: 5px;
38 | justify-content: center;
39 | margin: 10px 0;
40 | max-height: 150px;
41 | overflow: auto;
42 | }
43 | .old_photos img {
44 | width: 100px;
45 | height: 100px;
46 | object-fit: cover;
47 | border-radius: 10px;
48 | cursor: pointer;
49 | }
50 |
--------------------------------------------------------------------------------
/src/svg/send.js:
--------------------------------------------------------------------------------
1 | function Send({ color = "#0096ff" }) {
2 | return (
3 |
9 | );
10 | }
11 |
12 | export default Send;
13 |
--------------------------------------------------------------------------------
/src/components/FormLoader/style.module.css:
--------------------------------------------------------------------------------
1 | .wrap {
2 | position: relative;
3 | }
4 | .loader {
5 | position: absolute;
6 | left: 50%;
7 | top: 50%;
8 | -webkit-transform: translate(-50%, -50%);
9 | transform: translate(-50%, -50%);
10 | z-index: 10;
11 | }
12 | .content {
13 | filter: blur(2px);
14 | }
15 | .loaderback,
16 | .isError {
17 | background: #ffffff78;
18 | width: 100%;
19 | height: 100%;
20 | position: absolute;
21 | top: 0;
22 | left: 0;
23 | z-index: 1;
24 | }
25 | .isError {
26 | background: #ffffffb7;
27 | display: flex;
28 | justify-content: center;
29 | flex-direction: column;
30 | align-items: center;
31 | gap: 20px;
32 | color: var(--red-color);
33 | padding: 30px;
34 | text-align: center;
35 | }
36 | .isError button {
37 | width: auto;
38 | font-weight: unset;
39 | font-size: small;
40 | }
41 |
42 | :global(.dark) .isError {
43 | background: rgba(19, 19, 19, 0.59);
44 | }
45 | :global(.dark) .loaderback,
46 | .isError {
47 | background: rgba(25, 25, 25, 0.594);
48 | }
49 |
--------------------------------------------------------------------------------
/src/components/UI/Notification/Notification.module.css:
--------------------------------------------------------------------------------
1 | .main {
2 | display: flex;
3 | gap: 6px;
4 | flex-direction: column;
5 | background: var(--bg-primary);
6 | padding: 15px;
7 | border-radius: 10px;
8 | box-shadow: 0px 4px 7px var(--shadow-2);
9 | }
10 | .header {
11 | display: flex;
12 | justify-content: space-between;
13 | font-size: 14px;
14 | font-weight: 600;
15 | }
16 | .content {
17 | display: flex;
18 | align-items: center;
19 | justify-content: space-between;
20 | gap: 15px;
21 | font-size: 14px;
22 | font-weight: 400;
23 | cursor: pointer;
24 | }
25 |
26 | .content_2 {
27 | display: flex;
28 | flex-direction: column;
29 | }
30 | .img {
31 | position: relative;
32 | }
33 | .img img:nth-child(1) {
34 | width: 56px;
35 | height: 56px;
36 | border-radius: 100%;
37 | }
38 | .type {
39 | width: 28px;
40 | height: 28px;
41 | position: absolute;
42 | right: -5px;
43 | bottom: 0;
44 | }
45 |
46 | .time time {
47 | font-size: 12px;
48 | font-weight: 600;
49 | color: #0096ff;
50 | }
51 |
--------------------------------------------------------------------------------
/public/reacts/love.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/app/slices/soketSlice.js:
--------------------------------------------------------------------------------
1 | import { createSlice } from "@reduxjs/toolkit";
2 |
3 | // type = ['normal','image','background']
4 |
5 | const initialValue = {
6 | onlineUsers: [],
7 | selectedChat: null,
8 | };
9 | export const createSoketSlice = createSlice({
10 | name: "soketSlice",
11 | initialState: initialValue,
12 |
13 | reducers: {
14 | setOnlineUsers: (state, action) => {
15 | const { type, info } = action.payload;
16 | if (
17 | type === "add" &&
18 | !state.onlineUsers.find((u) => u?.id === info?.id)
19 | ) {
20 | state.onlineUsers = [...state.onlineUsers, info];
21 | } else if (type === "remove") {
22 | state.onlineUsers = state.onlineUsers.filter((u) => u?.id !== info?.id);
23 | } else if (type === "connect") {
24 | state.onlineUsers = info;
25 | }
26 | },
27 | setSelectedChat: (state, action) => {
28 | state.selectedChat = action.payload;
29 | },
30 | },
31 | });
32 | export const { setOnlineUsers, setSelectedChat } = createSoketSlice.actions;
33 |
34 | export default createSoketSlice.reducer;
35 |
--------------------------------------------------------------------------------
/src/components/home/stories/Stories.jsx:
--------------------------------------------------------------------------------
1 | import { Plus } from "../../../svg";
2 | import styles from "./Stories.module.css";
3 | import { stories } from "../../../data/home";
4 | import Story from "./Story";
5 | import Card from "../../UI/Card/Card";
6 | import { ScrollContainer } from "react-indiana-drag-scroll";
7 |
8 | function Stories() {
9 | return (
10 |
11 |
12 |
13 |
14 |

19 |
22 |
Create Story
23 |
24 | {stories.map((story, i) => (
25 |
26 | ))}
27 |
28 |
29 |
30 | );
31 | }
32 |
33 | export default Stories;
34 |
--------------------------------------------------------------------------------
/src/routes/router.jsx:
--------------------------------------------------------------------------------
1 | import { useSelector } from "react-redux";
2 | import { Route, Routes } from "react-router-dom";
3 | import ErrorPage from "../components/UI/Error/ErrorPage";
4 | import IsLoggedIn from "./IsLoggedIn";
5 | import NotLoggedIn from "./NotLoggedIn";
6 | import pagesData from "./pagesData";
7 |
8 | const Router = () => {
9 | const { soketSlice, user } = useSelector((state) => ({ ...state }));
10 |
11 | const pageRoutes = pagesData
12 | .filter(({ priv }) => !priv)
13 | .map(({ path, title, element }) => {
14 | return ;
15 | });
16 |
17 | const pageRoutesPriv = pagesData
18 | .filter(({ priv }) => priv)
19 | .map(({ path, title, element }) => {
20 | return ;
21 | });
22 |
23 | return (
24 |
25 | }>{pageRoutesPriv}
26 | }> {pageRoutes}
27 | } />
28 |
29 | );
30 | };
31 |
32 | export default Router;
33 |
--------------------------------------------------------------------------------
/src/svg/liveVideo.js:
--------------------------------------------------------------------------------
1 | function LiveVideo({ color }) {
2 | return (
3 |
15 | );
16 | }
17 |
18 | export default LiveVideo;
19 |
--------------------------------------------------------------------------------
/src/svg/friends.js:
--------------------------------------------------------------------------------
1 | function Friends({ color }) {
2 | return (
3 |
6 | );
7 | }
8 |
9 | export default Friends;
10 |
--------------------------------------------------------------------------------
/src/components/skeleton/PostSkeleton.jsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import classes from "../posts/post/Post.module.css";
3 | import Card from "../UI/Card/Card";
4 | import Skeleton from "react-loading-skeleton";
5 |
6 | function PostSkeleton() {
7 | return (
8 |
9 |
10 |
11 |
17 |
18 |
19 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 | );
35 | }
36 |
37 | export default PostSkeleton;
38 |
--------------------------------------------------------------------------------
/src/hooks/useSeenMessage.js:
--------------------------------------------------------------------------------
1 | import { useMutation } from "@tanstack/react-query";
2 | import axios from "axios";
3 | import { socket } from "../routes/IsLoggedIn";
4 | import { useDispatch } from "react-redux";
5 | import { updateNStats } from "../app/slices/userSlice";
6 | import { updateSeenMessages } from "../utils/rqUpdate";
7 |
8 | const SeenMessage = async ({ messageId }) => {
9 | const { data } = await axios.put(
10 | `${process.env.REACT_APP_BACKEND_URL}/api/v1/messages/${messageId}/seen`,
11 | {},
12 | {
13 | withCredentials: true,
14 | }
15 | );
16 | return data;
17 | };
18 |
19 | export const useSeenMessage = (chat) => {
20 | const dispatch = useDispatch();
21 |
22 | return useMutation({
23 | mutationKey: "useSeenMessage",
24 | mutationFn: SeenMessage,
25 | onSuccess: (data) => {
26 | const newMessage = data?.data?.message;
27 | const unseenMessages = data?.data?.unseenMessages;
28 |
29 | updateSeenMessages(newMessage, chat);
30 |
31 | dispatch(
32 | updateNStats({
33 | unseenMessages,
34 | })
35 | );
36 |
37 | socket.emit("seen", { message: newMessage, chat });
38 | },
39 | });
40 | };
41 |
--------------------------------------------------------------------------------
/src/components/posts/CreatePostPopup/AddToYourPost.jsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import { Dots, Feeling, Photo } from "../../../svg";
3 | import classes from "./CreatePostPopup.module.css";
4 | import { useDispatch } from "react-redux";
5 | import * as createPostSlice from "../../../app/slices/createPostSlice";
6 |
7 | function AddToYourPost() {
8 | const dispatch = useDispatch();
9 |
10 | return (
11 |
12 |
Add to your post
13 |
14 |
dispatch(createPostSlice.type("image"))}
17 | >
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 | );
35 | }
36 |
37 | export default AddToYourPost;
38 |
--------------------------------------------------------------------------------
/src/hooks/useRealationship.js:
--------------------------------------------------------------------------------
1 | import { useMutation } from "@tanstack/react-query";
2 | import axios from "axios";
3 | import { socket } from "../routes/IsLoggedIn";
4 | import { queryClient } from "./../App";
5 |
6 | const AddFriend = async ({ id, type }) => {
7 | const { data } = await axios.put(
8 | `${process.env.REACT_APP_BACKEND_URL}/api/v1/friends/${type}/${id}`,
9 | {},
10 | {
11 | withCredentials: true,
12 | }
13 | );
14 | return data;
15 | };
16 |
17 | export const useRelationship = (usernameID) => {
18 | return useMutation({
19 | mutationKey: "useRelationship",
20 | mutationFn: AddFriend,
21 | onSuccess: (data) => {
22 | const newNotification = data?.data?.newNotification;
23 |
24 | queryClient.setQueryData(["getProfile", usernameID], (oldData) => {
25 | if (!oldData) return oldData;
26 |
27 | let newData = oldData;
28 | newData.data.friendship = data.data.friendship;
29 | return oldData
30 | ? {
31 | ...oldData,
32 | newData,
33 | }
34 | : oldData;
35 | });
36 | if (newNotification) {
37 | socket.emit("notification", { notification: newNotification });
38 | }
39 | },
40 | });
41 | };
42 |
--------------------------------------------------------------------------------
/src/components/home/right/HomeRight.jsx:
--------------------------------------------------------------------------------
1 | import { Dots, NewRoom, Search } from "../../../svg";
2 | import Contact from "./Contact";
3 | import styles from "./HomeRight.module.css";
4 |
5 | function HomeRight({ user }) {
6 | const color = "#65676b";
7 |
8 | return (
9 |
10 |
Sponsored
11 |
12 |
13 |
14 |
Contacts
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 | );
33 | }
34 |
35 | export default HomeRight;
36 |
--------------------------------------------------------------------------------
/src/components/header/notificationMenu/NotificationMenu.module.css:
--------------------------------------------------------------------------------
1 | .menu {
2 | padding: 0 0.3rem;
3 | position: absolute;
4 | top: 100%;
5 | right: 0;
6 | width: calc(100vw - 20px);
7 | margin: 10px;
8 | max-width: 400px;
9 | border-radius: 10px;
10 | background: var(--bg-primary);
11 | box-shadow: 2px 2px 2px var(--shadow-1);
12 | user-select: none;
13 | padding: 10px;
14 | max-height: 600px;
15 | overflow: auto;
16 | }
17 | .menu h2 {
18 | padding: 10px;
19 | }
20 |
21 | .notification {
22 | padding: 10px;
23 | border-radius: 10px;
24 | }
25 |
26 | .content {
27 | display: flex;
28 | align-items: center;
29 | justify-content: flex-start;
30 | gap: 15px;
31 | font-size: 14px;
32 | font-weight: 400;
33 | cursor: pointer;
34 | }
35 |
36 | .content_2 {
37 | display: flex;
38 | flex-direction: column;
39 | flex: 1;
40 | }
41 | .img {
42 | position: relative;
43 | }
44 | .img img:nth-child(1) {
45 | width: 56px;
46 | height: 56px;
47 | border-radius: 100%;
48 | }
49 | .type {
50 | width: 28px;
51 | height: 28px;
52 | position: absolute;
53 | right: -5px;
54 | bottom: 0;
55 | }
56 |
57 | .time time {
58 | font-size: 12px;
59 | font-weight: 600;
60 | color: #0096ff;
61 | }
62 |
63 | :global(.dark) .menu i {
64 | filter: invert(100%);
65 | }
66 |
--------------------------------------------------------------------------------
/src/hooks/useSendMessage.js:
--------------------------------------------------------------------------------
1 | import { useMutation } from "@tanstack/react-query";
2 | import axios from "axios";
3 | import { toast } from "react-hot-toast";
4 | import { useSelector } from "react-redux";
5 | import { socket } from "../routes/IsLoggedIn";
6 | import { updateMessages } from "../utils/rqUpdate";
7 |
8 | export const useSendMessage = (chat) => {
9 | const user = useSelector((state) => ({ ...state.user.userinfo }));
10 |
11 | return useMutation({
12 | mutationKey: "useSendMessage",
13 | mutationFn: async ({ content, chatId, type }) => {
14 | updateMessages({
15 | _id: Math.floor(Math.random() * 100000000000 + 1),
16 | content,
17 | chat: chatId,
18 | type,
19 | sender: user,
20 | });
21 |
22 | const { data } = await axios.put(
23 | `${process.env.REACT_APP_BACKEND_URL}/api/v1/messages/${chatId}/send`,
24 | { content, type },
25 | {
26 | withCredentials: true,
27 | }
28 | );
29 | return data;
30 | },
31 | onError: (error) => {
32 | toast.error(error?.response?.data?.message);
33 | },
34 | onSuccess: (data) => {
35 | const newMessage = data?.data?.message;
36 |
37 | socket.emit("new_message", { message: newMessage, chat });
38 | },
39 | });
40 | };
41 |
--------------------------------------------------------------------------------
/src/hooks/useRenameGroup.js:
--------------------------------------------------------------------------------
1 | import { useMutation } from "@tanstack/react-query";
2 | import axios from "axios";
3 | import { socket } from "../routes/IsLoggedIn";
4 | import { updateChatName } from "../utils/rqUpdate";
5 | import { useSendMessage } from "./useSendMessage";
6 |
7 | const RenameGroup = async ({ chatId, chatName }) => {
8 | const { data } = await axios.put(
9 | `${process.env.REACT_APP_BACKEND_URL}/api/v1/chats/group/rename`,
10 | { chatId, chatName },
11 | {
12 | withCredentials: true,
13 | }
14 | );
15 | return data;
16 | };
17 |
18 | export const useRenameGroup = (chat) => {
19 | const { mutate: sendMessage } = useSendMessage(chat);
20 |
21 | return useMutation({
22 | mutationKey: "useRenameGroup",
23 | mutationFn: RenameGroup,
24 | onSuccess: (data) => {
25 | const newchatName = data?.data?.chatName;
26 | const userId = data?.data?.user;
27 |
28 | updateChatName(newchatName, chat._id);
29 |
30 | sendMessage({
31 | content: `Group name changed to ${newchatName}`,
32 | type: "info",
33 | chatId: chat._id,
34 | });
35 |
36 | socket.emit("customize_chat", {
37 | userId,
38 | type: "name",
39 | content: newchatName,
40 | chat,
41 | });
42 | },
43 | });
44 | };
45 |
--------------------------------------------------------------------------------
/src/hooks/useSeenNotification.js:
--------------------------------------------------------------------------------
1 | import { useMutation } from "@tanstack/react-query";
2 | import axios from "axios";
3 | import { queryClient } from "../App";
4 |
5 | const SeenNotification = async ({ nid }) => {
6 | const { data } = await axios.put(
7 | `${process.env.REACT_APP_BACKEND_URL}/api/v1/users/notifications/${nid}/seen`,
8 | {},
9 | {
10 | withCredentials: true,
11 | }
12 | );
13 | return data;
14 | };
15 |
16 | export const useSeenNotification = () => {
17 | return useMutation({
18 | mutationKey: "useSeenNotification",
19 | mutationFn: SeenNotification,
20 | onSuccess: (data) => {
21 | const newNotification = data?.data?.notification;
22 |
23 | queryClient.setQueryData(["getNotifications"], (oldData) => {
24 | if (!oldData) return oldData;
25 | let newData = oldData;
26 | newData.data.notifications = newData.data.notifications.map(
27 | (notification) => {
28 | if (notification._id === newNotification._id) {
29 | return {
30 | ...notification,
31 | seen: "seen",
32 | };
33 | }
34 | return notification;
35 | }
36 | );
37 | return {
38 | ...oldData,
39 | newData,
40 | };
41 | });
42 | },
43 | });
44 | };
45 |
--------------------------------------------------------------------------------
/src/svg/smile.js:
--------------------------------------------------------------------------------
1 | function Smile({ color = "#0096ff" }) {
2 | return (
3 |
17 | );
18 | }
19 |
20 | export default Smile;
21 |
--------------------------------------------------------------------------------
/src/svg/feeling.js:
--------------------------------------------------------------------------------
1 | function Feeling({ color }) {
2 | return (
3 |
20 | );
21 | }
22 |
23 | export default Feeling;
24 |
--------------------------------------------------------------------------------
/src/hooks/useAddMember.js:
--------------------------------------------------------------------------------
1 | import { useMutation } from "@tanstack/react-query";
2 | import axios from "axios";
3 | import { queryClient } from "../App";
4 | import { useSendMessage } from "./useSendMessage";
5 |
6 | const AddMember = async ({ chatId, userId }) => {
7 | const { data } = await axios.put(
8 | `${process.env.REACT_APP_BACKEND_URL}/api/v1/chats/group/add`,
9 | { chatId, userId },
10 | {
11 | withCredentials: true,
12 | }
13 | );
14 | return data;
15 | };
16 |
17 | export const useAddMember = (chat) => {
18 | const { mutate: sendMessage } = useSendMessage(chat);
19 |
20 | return useMutation({
21 | mutationKey: "useAddMember",
22 | mutationFn: AddMember,
23 | onSuccess: (data) => {
24 | const user = data?.data?.user;
25 |
26 | queryClient.setQueryData(["getMessages", chat._id], (oldData) => {
27 | if (!oldData) return oldData;
28 | let newData = oldData;
29 | newData.pages[0].data.chat.users = [
30 | user,
31 | ...newData.pages[0].data.chat.users,
32 | ];
33 |
34 | return {
35 | ...oldData,
36 | newData,
37 | };
38 | });
39 |
40 | sendMessage({
41 | content: `${user.first_name} ${user.last_name} Added to this group`,
42 | type: "info",
43 | chatId: chat._id,
44 | });
45 | },
46 | });
47 | };
48 |
--------------------------------------------------------------------------------
/src/pages/home/style.module.css:
--------------------------------------------------------------------------------
1 | .home {
2 | min-height: 100vh;
3 | background: var(--bg-secondary);
4 | display: grid;
5 | grid-template-columns: repeat(3, 1fr);
6 | }
7 |
8 | .home_middle {
9 | margin-top: 75px;
10 | position: absolute;
11 | left: 50%;
12 | transform: translateX(-50%);
13 | max-width: 590px;
14 | }
15 | .posts {
16 | margin-top: 10px;
17 | display: flex;
18 | flex-direction: column;
19 | gap: 10px;
20 | margin-bottom: 20px;
21 | }
22 |
23 | @media (max-width: 1175px) {
24 | .home_middle {
25 | margin-left: 5%;
26 | }
27 | .ActiveAccount {
28 | width: 84%;
29 | }
30 | }
31 | @media (max-width: 1030px) {
32 | .home_middle {
33 | position: relative;
34 | margin-left: 55px;
35 | }
36 | .ActiveAccount {
37 | width: 100%;
38 | }
39 | }
40 | @media (max-width: 960px) {
41 | .home_middle {
42 | margin-left: 10%;
43 | }
44 | .ActiveAccount {
45 | width: 93%;
46 | }
47 | }
48 |
49 | @media (max-width: 885px) {
50 | .ActiveAccount {
51 | width: 110%;
52 | }
53 | }
54 |
55 | @media (max-width: 620px) {
56 | .home_middle {
57 | position: absolute;
58 | margin-left: 0;
59 | width: 100%;
60 | padding: 6px;
61 | }
62 | .ActiveAccount {
63 | width: 100%;
64 | }
65 | }
66 | @media (max-width: 400px) {
67 | .home_middle {
68 | width: 100%;
69 | margin: 56px auto;
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/src/svg/photo.js:
--------------------------------------------------------------------------------
1 | function Photo({ color = "#0096ff" }) {
2 | return (
3 |
16 | );
17 | }
18 |
19 | export default Photo;
20 |
--------------------------------------------------------------------------------
/src/pages/post/PostPage.jsx:
--------------------------------------------------------------------------------
1 | import React, { useEffect } from "react";
2 | import classes from "./style.module.css";
3 | import { useParams } from "react-router-dom";
4 | import axios from "axios";
5 | import { useQuery } from "@tanstack/react-query";
6 | import Post from "../../components/posts/post";
7 | import PostSkeleton from "../../components/skeleton/PostSkeleton";
8 | import { useNavigate } from "react-router-dom";
9 |
10 | function PostPage() {
11 | const navigate = useNavigate();
12 |
13 | const { post } = useParams();
14 | const { isLoading, isError, data, isFetching, isSuccess } = useQuery({
15 | queryKey: ["getPost", post],
16 | queryFn: async () => {
17 | const { data } = await axios.get(
18 | `${process.env.REACT_APP_BACKEND_URL}/api/v1/posts/${post}`,
19 | {
20 | withCredentials: true,
21 | }
22 | );
23 | return data;
24 | },
25 | refetchOnWindowFocus: false,
26 | });
27 |
28 | const postsSkelton = isLoading || isFetching;
29 |
30 | useEffect(() => {
31 | if (isError) {
32 | navigate("/404");
33 | }
34 | }, [isError]);
35 |
36 | return (
37 |
38 |
39 | {postsSkelton &&
}
40 | {isSuccess && !isLoading &&
}
41 |
42 |
43 | );
44 | }
45 |
46 | export default PostPage;
47 |
--------------------------------------------------------------------------------
/src/components/home/SendVerification/SendVerification.module.css:
--------------------------------------------------------------------------------
1 | .ActiveAccount {
2 | width: 100%;
3 | margin: 5px 0;
4 | display: flex;
5 | flex-direction: column;
6 | font-size: smaller;
7 | }
8 | .done {
9 | width: 100%;
10 | margin: 5px 0;
11 | display: flex;
12 | flex-direction: row;
13 | font-size: smaller;
14 | align-items: center;
15 | justify-content: center;
16 | gap: 6px;
17 | }
18 | .done div:nth-child(2) {
19 | margin: 0 !important;
20 | }
21 |
22 | .ActiveAccount span {
23 | color: var(--color-secondary);
24 | }
25 | .ActiveAccount a {
26 | color: var(--blue-color);
27 | cursor: pointer;
28 | width: fit-content;
29 | }
30 | .ActiveAccount a:hover {
31 | text-decoration: underline;
32 | }
33 | .link {
34 | color: var(--blue-color);
35 | cursor: pointer;
36 | width: fit-content;
37 | }
38 | .link:hover {
39 | text-decoration: underline;
40 | }
41 | @media (max-width: 1175px) {
42 | .ActiveAccount,
43 | .done {
44 | width: 84%;
45 | }
46 | }
47 | @media (max-width: 1030px) {
48 | .ActiveAccount,
49 | .done {
50 | width: 100%;
51 | }
52 | }
53 | @media (max-width: 960px) {
54 | .ActiveAccount,
55 | .done {
56 | width: 93%;
57 | }
58 | }
59 |
60 | @media (max-width: 885px) {
61 | .ActiveAccount,
62 | .done {
63 | width: 100%;
64 | }
65 | }
66 |
67 | @media (max-width: 620px) {
68 | .ActiveAccount,
69 | .done {
70 | width: 100%;
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/src/hooks/useCreatePost.js:
--------------------------------------------------------------------------------
1 | import { useMutation } from "@tanstack/react-query";
2 | import axios from "axios";
3 | import { queryClient } from "./../App";
4 |
5 | const CreatePost = async ({ data, type }) => {
6 | const reqdata = axios.post(
7 | `${process.env.REACT_APP_BACKEND_URL}/api/v1/posts/createPost${
8 | type === "image" ? "/images" : ""
9 | }`,
10 | data,
11 | {
12 | withCredentials: true,
13 | }
14 | );
15 | return reqdata;
16 | };
17 |
18 | export const useCreatePost = (usernameID) => {
19 | return useMutation({
20 | mutationKey: "useCreatePost",
21 | mutationFn: CreatePost,
22 | onSuccess: (data) => {
23 | queryClient.setQueryData(["getProfilePosts", usernameID], (oldData) => {
24 | if (!oldData) return;
25 |
26 | let newData = oldData;
27 | const newPost = data.data.data;
28 | newData.pages[0].data = [newPost, ...newData.pages[0].data];
29 | return {
30 | ...oldData,
31 | newData,
32 | };
33 | });
34 |
35 | queryClient.setQueryData(["allPosts"], (oldData) => {
36 | if (!oldData) return oldData;
37 |
38 | let newData = oldData;
39 | const newPost = data.data.data;
40 | newData.pages[0].data = [newPost, ...newData?.pages[0]?.data];
41 | return {
42 | ...oldData,
43 | newData,
44 | };
45 | });
46 | },
47 | });
48 | };
49 |
--------------------------------------------------------------------------------
/public/reacts/like.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/hooks/useRemoveMember.js:
--------------------------------------------------------------------------------
1 | import { useMutation } from "@tanstack/react-query";
2 | import axios from "axios";
3 | import { queryClient } from "../App";
4 | import { useSendMessage } from "./useSendMessage";
5 |
6 | const RemoveMember = async ({ chatId, userId }) => {
7 | const { data } = await axios.put(
8 | `${process.env.REACT_APP_BACKEND_URL}/api/v1/chats/group/remove`,
9 | { chatId, userId },
10 | {
11 | withCredentials: true,
12 | }
13 | );
14 | return data;
15 | };
16 |
17 | export const useRemoveMember = (chat) => {
18 | const { mutate: sendMessage } = useSendMessage(chat);
19 |
20 | return useMutation({
21 | mutationKey: "useRemoveMember",
22 | mutationFn: RemoveMember,
23 | onSuccess: (data) => {
24 | const userId = data?.data?.user;
25 | const deletedUser = data?.data?.deletedUser;
26 |
27 | queryClient.setQueryData(["getMessages", chat._id], (oldData) => {
28 | if (!oldData) return oldData;
29 | let newData = oldData;
30 | newData.pages[0].data.chat.users =
31 | newData.pages[0].data.chat.users.filter((m) => m._id !== userId);
32 |
33 | return {
34 | ...oldData,
35 | newData,
36 | };
37 | });
38 |
39 | sendMessage({
40 | content: `${deletedUser.first_name} ${deletedUser.last_name} Removed from this group`,
41 | type: "info",
42 | chatId: chat._id,
43 | });
44 | },
45 | });
46 | };
47 |
--------------------------------------------------------------------------------
/src/components/posts/post/shares/CreateSharePost.module.css:
--------------------------------------------------------------------------------
1 | .wrap {
2 | display: flex;
3 | align-items: center;
4 | justify-content: center;
5 | }
6 | .card {
7 | width: 100%;
8 | max-width: 700px;
9 | padding: 0;
10 | margin: 8px;
11 | max-height: 98vh;
12 | overflow: auto;
13 | }
14 | .header {
15 | display: flex;
16 | align-items: center;
17 | justify-content: center;
18 | padding: 16px 0;
19 | border-bottom: 1px solid var(--divider);
20 | font-size: 20px;
21 | font-weight: 700;
22 | position: relative;
23 | }
24 | .header div {
25 | position: absolute;
26 | right: 0;
27 | }
28 | .content {
29 | padding: 16px;
30 | display: flex;
31 | flex-direction: column;
32 | gap: 16px;
33 | }
34 | .textarea_blue {
35 | width: 100%;
36 | height: 80px;
37 | resize: none;
38 | border-radius: 7px;
39 | outline-offset: 5px;
40 | border-color: var(--bg-third);
41 | padding: 0.8rem;
42 | font-size: 16px;
43 | font-family: inherit;
44 | background: var(--bg-primary);
45 | color: var(--color-primary);
46 | margin-bottom: 10px;
47 | }
48 |
49 | .textarea_blue:focus {
50 | outline-color: var(--blue-color);
51 | }
52 |
53 | .textarea_blue:hover {
54 | border-color: var(--color-secondary);
55 | }
56 |
57 | .btns {
58 | margin-top: 10px;
59 | display: flex;
60 | justify-content: flex-end;
61 | gap: 10px;
62 | }
63 |
64 | .btns button {
65 | width: -webkit-fill-available;
66 | font-weight: 500;
67 | font-size: 15px;
68 | }
69 |
--------------------------------------------------------------------------------
/src/components/posts/post/likes/ReactsPopup.jsx:
--------------------------------------------------------------------------------
1 | import { useRef } from "react";
2 | import useOnClickOutside from "../../../../hooks/useOnClickOutside";
3 | import styles from "./ReactsPopup.module.css";
4 |
5 | const reactsArray = [
6 | {
7 | name: "like",
8 | image: "../../../reacts/like.gif",
9 | },
10 | {
11 | name: "love",
12 | image: "../../../reacts/love.gif",
13 | },
14 | {
15 | name: "haha",
16 | image: "../../../reacts/haha.gif",
17 | },
18 | {
19 | name: "wow",
20 | image: "../../../reacts/wow.gif",
21 | },
22 | {
23 | name: "sad",
24 | image: "../../../reacts/sad.gif",
25 | },
26 | {
27 | name: "angry",
28 | image: "../../../reacts/angry.gif",
29 | },
30 | ];
31 |
32 | export default function ReactsPopup({
33 | handleMouseEnter,
34 | handleMouseLeave,
35 | reactHandler,
36 | setShowReact,
37 | showReact,
38 | }) {
39 | const popUpRef = useRef();
40 | useOnClickOutside(popUpRef, showReact, () => {
41 | setShowReact(false);
42 | });
43 | return (
44 |
50 | {reactsArray.map((react, i) => (
51 |
reactHandler(react.name)}
55 | >
56 |

57 |
58 | ))}
59 |
60 | );
61 | }
62 |
--------------------------------------------------------------------------------
/src/svg/index.js:
--------------------------------------------------------------------------------
1 | import Logo from "./logo";
2 | import HomeActive from "./homeActive";
3 | import Friends from "./friends.js";
4 | import Watch from "./watch";
5 | import Market from "./market";
6 | import Gaming from "./gaming";
7 | import Menu from "./menu";
8 | import Messenger from "./messenger";
9 | import ArrowDown from "./arrowDown";
10 | import Notifications from "./notifications";
11 | import Search from "./search";
12 | import Return from "./return";
13 | import ArrowDown1 from "./arrowDow1";
14 | import Plus from "./plus";
15 | import ArrowRight from "./arrowRight";
16 | import LiveVideo from "./liveVideo";
17 | import Photo from "./photo";
18 | import Feeling from "./feeling";
19 | import Dots from "./dots";
20 | import Public from "./public";
21 | import NewRoom from "./newRoom";
22 | import Home from "./home";
23 | import FriendsActive from "./friendsActive";
24 | import Info from "./info";
25 | import Like from "./like";
26 | import Smile from "./smile";
27 | import Send from "./send";
28 | import UnSeen from "./unseen";
29 | import Phone from "./phone";
30 |
31 | export {
32 | Logo,
33 | HomeActive,
34 | Friends,
35 | Watch,
36 | Market,
37 | Gaming,
38 | Menu,
39 | Messenger,
40 | Notifications,
41 | ArrowDown,
42 | Search,
43 | Return,
44 | ArrowDown1,
45 | Plus,
46 | ArrowRight,
47 | LiveVideo,
48 | Photo,
49 | Feeling,
50 | Dots,
51 | Public,
52 | NewRoom,
53 | Home,
54 | FriendsActive,
55 | Info,
56 | Like,
57 | Smile,
58 | Send,
59 | UnSeen,
60 | Phone,
61 | };
62 |
--------------------------------------------------------------------------------
/src/hooks/useChangeTheme.js:
--------------------------------------------------------------------------------
1 | import { useMutation } from "@tanstack/react-query";
2 | import axios from "axios";
3 | import { toast } from "react-hot-toast";
4 | import { chatThemes } from "../data/chatThemes";
5 | import { socket } from "../routes/IsLoggedIn";
6 | import { updateChatTheme } from "../utils/rqUpdate";
7 | import { useSendMessage } from "./useSendMessage";
8 |
9 | const ChangeTheme = async ({ theme, chatId }) => {
10 | const { data } = await axios.put(
11 | `${process.env.REACT_APP_BACKEND_URL}/api/v1/chats/${chatId}/theme`,
12 | { theme },
13 | {
14 | withCredentials: true,
15 | }
16 | );
17 | return data;
18 | };
19 |
20 | export const useChangeTheme = (chat) => {
21 | const { mutate: sendMessage } = useSendMessage(chat);
22 |
23 | return useMutation({
24 | mutationKey: "useChangeTheme",
25 | mutationFn: ChangeTheme,
26 | onSuccess: (data) => {
27 | const newTheme = data?.data?.theme;
28 | const name = data?.data?.name;
29 | const userId = data?.data?.user;
30 |
31 | updateChatTheme(newTheme, chat._id);
32 |
33 | sendMessage({
34 | content: `
35 | ${name} changed the theme to ${chatThemes[newTheme - 1].name}.`,
36 | type: "info",
37 | chatId: chat._id,
38 | });
39 |
40 | toast.success("Theme changed successfully");
41 |
42 | socket.emit("customize_chat", {
43 | userId,
44 | type: "theme",
45 | content: newTheme,
46 | chat,
47 | });
48 | },
49 | });
50 | };
51 |
--------------------------------------------------------------------------------
/src/components/FormLoader/index.jsx:
--------------------------------------------------------------------------------
1 | import React, { useState, useEffect } from "react";
2 | import BeatLoader from "react-spinners/BeatLoader";
3 | import PulseLoader from "react-spinners/PulseLoader";
4 |
5 | import styles from "./style.module.css";
6 | function FormLoader({ children, loading, className, isError, type }) {
7 | const [shoswError, setShowError] = useState(isError);
8 | const error = shoswError;
9 |
10 | useEffect(() => {
11 | setShowError(isError);
12 | }, [isError]);
13 |
14 | return (
15 |
18 | {loading ?
: ""}
19 | {error ? (
20 |
21 |
{isError?.response?.data.message}
22 |
25 |
26 | ) : (
27 | ""
28 | )}
29 | {loading ? (
30 |
31 | {type === 2 ? (
32 |
33 | ) : (
34 |
35 | )}
36 |
37 | ) : (
38 | ""
39 | )}
40 |
41 | {children}
42 |
43 |
44 | );
45 | }
46 |
47 | export default FormLoader;
48 |
--------------------------------------------------------------------------------
/src/pages/forgot/index.jsx:
--------------------------------------------------------------------------------
1 | import React, { useState } from "react";
2 | import ChangePassword from "../../components/forgot/ChangePassword";
3 | import CodeVerification from "../../components/forgot/CodeVerification";
4 | import SearchAccount from "../../components/forgot/SearchAccount";
5 | import SendEmail from "../../components/forgot/SendEmail";
6 | import LoginFooter from "../../components/login/LoginFooter";
7 | import NoAuthHeader from "../../components/noAuthHeader";
8 | import styles from "./style.module.css";
9 |
10 | function Forgot() {
11 | const [visible, setVisible] = useState(0);
12 | const [userInfos, setUserInfos] = useState("");
13 |
14 | return (
15 |
16 |
17 |
18 | {visible === 0 && (
19 |
20 | )}
21 | {visible === 1 && (
22 |
23 | )}
24 | {visible === 2 && (
25 |
30 | )}
31 | {visible === 3 && (
32 |
37 | )}
38 |
39 |
40 |
41 | );
42 | }
43 |
44 | export default Forgot;
45 |
--------------------------------------------------------------------------------
/src/components/input/signup/index.jsx:
--------------------------------------------------------------------------------
1 | import React, { useState } from "react";
2 | import styles from "./style.module.css";
3 | import { useField, ErrorMessage } from "formik";
4 | import { useMediaQuery } from "react-responsive";
5 | import Popper from "../../Popper/Popper";
6 |
7 | function LoginInput({ placeholder, dir, type, disabled, ...props }) {
8 | const [field, meta] = useField(props);
9 | const [trigger, setTrigger] = useState(null);
10 | const [show, setShow] = useState(false);
11 |
12 | const desktopView = useMediaQuery({
13 | query: "(min-width: 850px)",
14 | });
15 |
16 | return (
17 |
18 | {meta.touched && meta.error && show && (
19 |
24 |
25 |
26 | )}
27 |
setShow(true)}
36 | onBlurCapture={(e) => {
37 | setShow(false);
38 | }}
39 | />
40 | {meta.touched && meta.error && (
41 |
42 | )}
43 |
44 | );
45 | }
46 |
47 | export default LoginInput;
48 |
--------------------------------------------------------------------------------
/src/App.js:
--------------------------------------------------------------------------------
1 | import { useEffect } from "react";
2 | import Router from "./routes/router";
3 | import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
4 | import CreatePostPopup from "./components/posts/CreatePostPopup";
5 | import { useSelector } from "react-redux";
6 | import { Toaster } from "react-hot-toast";
7 | import Portal from "./utils/Portal";
8 |
9 | export const queryClient = new QueryClient();
10 |
11 | function App() {
12 | const user = useSelector((state) => ({ ...state.user.userinfo }));
13 | const theme = useSelector((state) => state.user.theme);
14 | const createPost = useSelector((state) => state.createPost);
15 |
16 | window.oncontextmenu = function (event) {
17 | event.preventDefault();
18 | event.stopPropagation();
19 | return false;
20 | };
21 |
22 | useEffect(() => {
23 | if (theme === "dark") {
24 | document.body.classList.add("dark");
25 | } else {
26 | document.body.classList.remove("dark");
27 | }
28 | }, [theme]);
29 |
30 | useEffect(() => {
31 | if (createPost.isOpen) {
32 | document.documentElement.style.overflow = "hidden";
33 | } else {
34 | document.documentElement.style.overflow = "auto";
35 | }
36 | }, [createPost.isOpen]);
37 |
38 | return (
39 |
40 | {createPost.isOpen && }
41 |
42 |
43 |
44 |
45 |
46 | );
47 | }
48 |
49 | export default App;
50 |
--------------------------------------------------------------------------------
/src/app/slices/createPostSlice.js:
--------------------------------------------------------------------------------
1 | import { createSlice } from "@reduxjs/toolkit";
2 |
3 | // type = ['normal','image','background']
4 |
5 | const initialValue = {
6 | isOpen: false,
7 | type: "normal",
8 | postText: "",
9 | background: null,
10 | images: [],
11 | };
12 | export const createPostSlice = createSlice({
13 | name: "createPost",
14 | initialState: initialValue,
15 |
16 | reducers: {
17 | type: (state, action) => {
18 | state.type = action.payload;
19 | if (action.payload === "normal" || action.payload === "background") {
20 | state.images = [];
21 | }
22 | },
23 | images: (state, action) => {
24 | state.images.push(action.payload);
25 | },
26 | background: (state, action) => {
27 | state.type = "background";
28 | state.background = action.payload;
29 | },
30 | postText: (state, action) => {
31 | state.postText = action.payload;
32 | },
33 | open: (state, action) => {
34 | if (state.isOpen) state.type = "normal";
35 | state.isOpen = !state.isOpen;
36 | if (action.payload === "photo") state.type = "image";
37 | },
38 | success: (state, action) => {
39 | state.isOpen = initialValue.isOpen;
40 | state.type = initialValue.type;
41 | state.postText = initialValue.postText;
42 | state.background = initialValue.background;
43 | state.images = initialValue.images;
44 | },
45 | },
46 | });
47 | export const { type, images, background, postText, open, success } =
48 | createPostSlice.actions;
49 |
50 | export default createPostSlice.reducer;
51 |
--------------------------------------------------------------------------------
/src/components/input/login/index.jsx:
--------------------------------------------------------------------------------
1 | import React, { useState } from "react";
2 | import styles from "./input.module.css";
3 | import { useField, ErrorMessage } from "formik";
4 | import { useMediaQuery } from "react-responsive";
5 | import Popper from "../../Popper/Popper";
6 |
7 | function LoginInput({ placeholder, type, disabled, className, ...props }) {
8 | const [field, meta] = useField(props);
9 | const [trigger, setTrigger] = useState(null);
10 | const [show, setShow] = useState(false);
11 |
12 | const desktopView = useMediaQuery({
13 | query: "(min-width: 850px)",
14 | });
15 |
16 | return (
17 |
18 | {meta.touched && meta.error && show && (
19 |
24 |
25 |
26 | )}
27 |
setShow(true)}
36 | onBlurCapture={(e) => {
37 | setShow(false);
38 | }}
39 | />
40 | {meta.touched && meta.error && (
41 |
42 | )}
43 |
44 | );
45 | }
46 |
47 | export default LoginInput;
48 |
--------------------------------------------------------------------------------
/src/svg/market.js:
--------------------------------------------------------------------------------
1 | function Market({ color }) {
2 | return (
3 |
6 | );
7 | }
8 |
9 | export default Market;
10 |
--------------------------------------------------------------------------------
/src/pages/profile/Photos.jsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import { Link } from "react-router-dom";
3 | import Card from "../../components/UI/Card/Card";
4 | import classes from "./style.module.css";
5 | import PuffLoader from "react-spinners/PuffLoader";
6 | import Skeleton from "react-loading-skeleton";
7 |
8 | function Photos({ photosData, photosSkelton }) {
9 | return (
10 |
11 |
12 | Photos
13 |
14 | See all photos
15 |
16 |
17 |
18 |
19 | {photosSkelton ? (
20 |
21 | ) : (
22 | `${photosData.total_count} photos`
23 | )}
24 |
25 |
26 | {photosSkelton ? (
27 |
30 | ) : (
31 |
32 | {photosData.resources &&
33 | photosData.resources
34 | .slice(0, 9)
35 | .map((img) => (
36 |
41 | ))}
42 |
43 | )}
44 |
45 |
46 | );
47 | }
48 |
49 | export default Photos;
50 |
--------------------------------------------------------------------------------
/src/svg/phone.js:
--------------------------------------------------------------------------------
1 | function Phone({ color = "#0096ff" }) {
2 | return (
3 |
17 | );
18 | }
19 |
20 | export default Phone;
21 |
--------------------------------------------------------------------------------
/src/components/messages/chatTheme/ChatTheme.module.css:
--------------------------------------------------------------------------------
1 | .wrap {
2 | display: flex;
3 | justify-content: center;
4 | align-items: center;
5 | }
6 |
7 | .card {
8 | width: 97%;
9 | max-width: 450px;
10 | padding: 0 !important;
11 | margin: 0 6px;
12 | box-shadow: 0 6px 28px 0 var(--shadow-2), 0 2px 4px 0 var(--shadow-1),
13 | inset 0 0 0 1px var(--shadow-inset) !important;
14 | border: none;
15 | }
16 | .header {
17 | display: flex;
18 | justify-content: center;
19 | align-items: center;
20 | height: 60px;
21 | border-bottom: 1px solid var(--divider);
22 | position: relative;
23 | }
24 | .header span {
25 | font-size: 18px;
26 | font-weight: 700;
27 | }
28 | .exit {
29 | position: absolute;
30 | right: 5px;
31 | }
32 | .content {
33 | padding: 15px;
34 | }
35 | .themes {
36 | display: flex;
37 | flex-wrap: wrap;
38 | }
39 | .theme {
40 | position: relative;
41 | flex-basis: calc(16.666666666% - 10px);
42 | box-sizing: border-box;
43 | border-radius: 15px;
44 | cursor: pointer;
45 | margin: 5px;
46 | }
47 | .theme::before {
48 | content: "";
49 | display: block;
50 | padding-top: 100%;
51 | }
52 |
53 | .theme_wrap {
54 | position: absolute;
55 | top: 0;
56 | left: 0;
57 | height: 100%;
58 | width: 100%;
59 | display: flex;
60 | justify-content: center;
61 | align-items: center;
62 | }
63 | .theme_con {
64 | width: 48px;
65 | height: 48px;
66 | border-radius: 100%;
67 | background: red;
68 | }
69 |
70 | .btns {
71 | display: flex;
72 | justify-content: flex-end;
73 | gap: 10px;
74 | }
75 |
76 | .btns button {
77 | font-size: 14px;
78 | font-weight: 600;
79 | width: auto;
80 | }
81 |
--------------------------------------------------------------------------------
/src/components/login/LoginForm.module.css:
--------------------------------------------------------------------------------
1 | .main {
2 | height: 78vh;
3 | min-height: 600px;
4 | padding-top: 2rem;
5 | }
6 | .header {
7 | margin: 0 auto;
8 | width: 300px;
9 | display: flex;
10 | flex-direction: column;
11 | align-items: center;
12 | }
13 | .header img {
14 | width: 80%;
15 | }
16 | .header span {
17 | font-size: 20px;
18 | }
19 | .login {
20 | display: flex;
21 | align-items: center;
22 | flex-direction: column;
23 | }
24 | .login button {
25 | height: 50px;
26 | }
27 | .login_wrapper {
28 | width: 350px;
29 | display: flex;
30 | flex-direction: column;
31 | align-items: center;
32 | gap: 1rem;
33 | margin: 1rem auto;
34 | }
35 | .form {
36 | width: 100%;
37 | }
38 | .forgot {
39 | color: var(--blue);
40 | cursor: pointer;
41 | font-size: 14px;
42 | }
43 | .forgot:hover {
44 | text-decoration: underline;
45 | }
46 | .signup_btn {
47 | background: var(--green-color);
48 | font-size: 17px !important;
49 | font-weight: 600 !important;
50 | margin-top: 1rem;
51 | width: 70% !important;
52 | }
53 | .extra {
54 | font-size: 15px;
55 | }
56 | .error_text {
57 | color: var(--color-error);
58 | text-align: center;
59 | margin: 0 auto 10px;
60 | }
61 |
62 | @media (min-width: 900px) {
63 | .main {
64 | align-items: center;
65 | display: flex;
66 | margin: 0 auto;
67 | max-width: 1000px;
68 | }
69 | .header {
70 | width: 50%;
71 | margin: 0 auto 8rem;
72 | align-items: start;
73 | }
74 | .header span {
75 | font-size: 27px;
76 | }
77 | .header img {
78 | width: 300px;
79 | margin-left: -1.4rem;
80 | }
81 | .login_wrapper {
82 | width: 400px;
83 | }
84 | }
85 |
--------------------------------------------------------------------------------
/src/svg/public.js:
--------------------------------------------------------------------------------
1 | function Public({ color }) {
2 | return (
3 |
20 | );
21 | }
22 |
23 | export default Public;
24 |
--------------------------------------------------------------------------------
/src/components/profile/intro/EditDetails.module.css:
--------------------------------------------------------------------------------
1 | .wrap {
2 | display: flex;
3 | align-items: center;
4 | justify-content: center;
5 | }
6 | .card {
7 | width: 100%;
8 | max-width: 700px;
9 | min-height: 70vh;
10 | padding: 0;
11 | margin: 8px;
12 | }
13 | .header {
14 | display: flex;
15 | align-items: center;
16 | justify-content: center;
17 | padding: 16px 0;
18 | border-bottom: 1px solid var(--divider);
19 | font-size: 20px;
20 | font-weight: 700;
21 | position: relative;
22 | }
23 | .header div {
24 | position: absolute;
25 | right: 0;
26 | }
27 | .content {
28 | padding: 16px;
29 | display: flex;
30 | flex-direction: column;
31 | gap: 16px;
32 | overflow: scroll;
33 | max-height: 600px;
34 | }
35 | .h_col {
36 | display: flex;
37 | flex-direction: column;
38 | }
39 | .t1 {
40 | font-size: 16px;
41 | font-weight: 600;
42 | }
43 | .t2 {
44 | font-size: 14px;
45 | font-weight: 400;
46 | color: var(--color-secondary);
47 | }
48 | .details_header {
49 | margin-top: 15px;
50 | font-weight: 600;
51 | font-size: 20px;
52 | }
53 |
54 | .add_details_flex {
55 | display: flex;
56 | align-items: center;
57 | gap: 0.8rem;
58 | margin-top: 15px;
59 | color: var(--blue-color);
60 | font-size: 14px;
61 | cursor: pointer;
62 | }
63 |
64 | .add_details_flex i {
65 | right: 1rem;
66 | cursor: pointer;
67 | transform: scale(0.9);
68 | }
69 | .info_profile {
70 | margin-top: 10px;
71 | display: flex;
72 | align-items: center;
73 | gap: 10px;
74 | font-size: 15px;
75 | color: var(--color-primary);
76 | width: 100%;
77 | }
78 |
79 | .info_profile img {
80 | filter: invert(40%);
81 | }
82 | .underline:hover {
83 | text-decoration: underline;
84 | }
85 |
--------------------------------------------------------------------------------
/src/components/profile/intro/Detail.jsx:
--------------------------------------------------------------------------------
1 | import { useState, useRef } from "react";
2 | import useOnClickOutside from "../../../hooks/useOnClickOutside";
3 | import EditArea from "./EditArea";
4 | import classes from "./EditDetails.module.css";
5 |
6 | function Detail({
7 | img,
8 | value,
9 | placeholder,
10 | name,
11 | handleChange,
12 | updateDetails,
13 | infos,
14 | text,
15 | max,
16 | details,
17 | rel,
18 | }) {
19 | const [show, setShow] = useState(false);
20 |
21 | const editAreaRef = useRef(null);
22 |
23 | useOnClickOutside(editAreaRef, show, () => {
24 | setShow(false);
25 | });
26 | return (
27 |
28 |
setShow(true)}
31 | ref={editAreaRef}
32 | >
33 | {value ? (
34 |
35 |

36 | {value}
37 |
38 |
39 | ) : (
40 | <>
41 |
42 |
Add {text}
43 | >
44 | )}
45 |
46 | {show && (
47 |
59 | )}
60 |
61 | );
62 | }
63 |
64 | export default Detail;
65 |
--------------------------------------------------------------------------------
/src/pages/friends/FreindCard.jsx:
--------------------------------------------------------------------------------
1 | import { Link } from "react-router-dom";
2 | import { useEffect } from "react";
3 | import { useRelationship } from "../../hooks/useRealationship";
4 | import classes from "./style.module.css";
5 |
6 | export default function FriendCard({ user, type, requestId, refetch }) {
7 | const { mutate, data } = useRelationship(user.username);
8 |
9 | const acceptRequest = async (requestId) => {
10 | mutate({ id: requestId, type: "acceptRequest" });
11 | };
12 |
13 | const cancelRequestHandler = async (userId) => {
14 | mutate({ id: requestId, type: "cancel" });
15 | };
16 |
17 | useEffect(() => {
18 | if (data?.status === "success") {
19 | refetch();
20 | }
21 | }, [data]);
22 |
23 | return (
24 |
25 |
26 |

27 |
28 | {user.first_name} {user.last_name}
29 |
30 |
31 | {type === "sent" ? (
32 |
33 |
39 |
40 | ) : type === "request" ? (
41 |
42 |
45 |
51 |
52 | ) : (
53 | ""
54 | )}
55 |
56 | );
57 | }
58 |
--------------------------------------------------------------------------------
/src/svg/search.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | function Search({ color }) {
4 | return (
5 |
25 | );
26 | }
27 |
28 | export default Search;
29 |
--------------------------------------------------------------------------------
/src/routes/pagesData.jsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 |
3 | const Home = React.lazy(() => import("../pages/home"));
4 | const Login = React.lazy(() => import("../pages/login"));
5 | const Forgot = React.lazy(() => import("../pages/forgot"));
6 | const Profile = React.lazy(() => import("../pages/profile"));
7 | const FriendsPage = React.lazy(() => import("../pages/friends"));
8 | const PostPage = React.lazy(() => import("../pages/post/PostPage"));
9 | const Messages = React.lazy(() => import("../pages/messages"));
10 |
11 | const pagesData = [
12 | {
13 | path: "",
14 | element: ,
15 | title: "home",
16 | priv: true,
17 | },
18 | {
19 | path: "/activate/:token",
20 | element: ,
21 | title: "home",
22 | priv: true,
23 | },
24 | {
25 | path: "/profile",
26 | element: ,
27 | title: "profile",
28 | priv: true,
29 | },
30 | {
31 | path: "/messages",
32 | element: ,
33 | title: "messages",
34 | priv: true,
35 | },
36 | {
37 | path: "/messages/:chatId",
38 | element: ,
39 | title: "messages",
40 | priv: true,
41 | },
42 | {
43 | path: "/friends",
44 | element: ,
45 | title: "profile",
46 | priv: true,
47 | },
48 | {
49 | path: "/friends/:type",
50 | element: ,
51 | title: "profile",
52 | priv: true,
53 | },
54 | {
55 | path: "/profile/:username",
56 | element: ,
57 | title: "profile",
58 | priv: true,
59 | },
60 | {
61 | path: "/:username/posts/:post",
62 | element: ,
63 | title: "profile",
64 | priv: true,
65 | },
66 | {
67 | path: "forgot",
68 | element: ,
69 | title: "home",
70 | priv: false,
71 | },
72 | {
73 | path: "login",
74 | element: ,
75 | title: "login",
76 | priv: false,
77 | },
78 | ];
79 |
80 | export default pagesData;
81 |
--------------------------------------------------------------------------------
/src/components/home/posts/CreatePost/CreatePost.jsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import { Feeling, LiveVideo, Photo } from "../../../../svg";
3 | import styles from "./CreatePost.module.css";
4 | import * as createPostSlice from "../../../../app/slices/createPostSlice";
5 | import { useSelector, useDispatch } from "react-redux";
6 |
7 | function CreatePost({ user, profile }) {
8 | const dispatch = useDispatch();
9 | const createPost = useSelector((state) => state.createPost);
10 |
11 | return (
12 |
13 |
14 |

15 |
{
18 | dispatch(createPostSlice.open());
19 | }}
20 | >
21 | {createPost.postText
22 | ? createPost.postText
23 | : ` What's on your mind, ${user?.first_name}`}
24 |
25 |
26 |
27 |
28 |
29 |
30 | Live Video
31 |
32 |
33 |
{
36 | dispatch(createPostSlice.open("photo"));
37 | }}
38 | >
39 |
40 | Photo/Video
41 |
42 | {profile ? (
43 |
44 |
45 | Life Event
46 |
47 | ) : (
48 |
49 |
50 | Feeling/Activity
51 |
52 | )}
53 |
54 |
55 | );
56 | }
57 |
58 | export default CreatePost;
59 |
--------------------------------------------------------------------------------
/src/components/profile/intro/intro.module.css:
--------------------------------------------------------------------------------
1 | .card_header {
2 | font-size: 20px;
3 | font-weight: 700;
4 | display: flex;
5 | justify-content: space-between;
6 | }
7 | .content {
8 | display: flex;
9 | flex-direction: column;
10 | align-items: flex-start;
11 | }
12 | .info_profile {
13 | margin-top: 10px;
14 | display: flex;
15 | align-items: center;
16 | gap: 10px;
17 | font-size: 15px;
18 | color: var(--color-primary);
19 | }
20 |
21 | .info_profile img {
22 | filter: invert(40%);
23 | }
24 | .bio {
25 | white-space: pre-line;
26 | padding: 4px;
27 | text-align: center;
28 | margin-bottom: 10px;
29 | width: 100%;
30 | word-break: break-all;
31 | }
32 | .edit_btn {
33 | width: 100%;
34 | margin: 10px 0;
35 | }
36 | .bio_wrap {
37 | width: 100%;
38 | display: flex;
39 | flex-direction: column;
40 | gap: 10px;
41 | }
42 | .textarea_blue {
43 | margin-top: 10px;
44 | width: 100%;
45 | height: 80px;
46 | resize: none;
47 | border-radius: 4px;
48 | outline-offset: 4px;
49 | border: 1px solid var(--bg-third);
50 | padding: 0.8rem;
51 | font-size: 16px;
52 | font-family: inherit;
53 | background: var(--bg-secondary);
54 | color: var(--color-primary);
55 | }
56 |
57 | .textarea_blue:focus {
58 | outline-color: var(--blue-color);
59 | background: var(--bg-primary);
60 | }
61 |
62 | .textarea_blue:hover {
63 | border-color: var(--color-secondary);
64 | background: var(--bg-secondary);
65 | }
66 | .remaining {
67 | font-size: 12px;
68 | color: var(--color-secondary);
69 | align-self: flex-end;
70 | margin-top: 2px;
71 | }
72 | .save_btns {
73 | display: flex;
74 | justify-content: flex-end;
75 | gap: 10px;
76 | }
77 | .save_btns button {
78 | width: auto;
79 | font-weight: 600;
80 | font-size: 14px;
81 | }
82 | .select_rel {
83 | height: 30px;
84 | outline: none;
85 | border: none;
86 | background: var(--bg-secondary);
87 | margin: 10px 0;
88 | padding: 0 10px;
89 | border-radius: 5px;
90 | }
91 |
--------------------------------------------------------------------------------
/src/components/posts/post/comments/CreateComment.module.css:
--------------------------------------------------------------------------------
1 | .wrap {
2 | padding: 5px 0px;
3 | display: flex;
4 | align-items: center;
5 | gap: 10px;
6 | margin-bottom: 5px;
7 | }
8 |
9 | .left {
10 | display: flex;
11 | text-align: center;
12 | justify-content: center;
13 | }
14 | .left img {
15 | width: 32px;
16 | height: 32px;
17 | border-radius: 50%;
18 | }
19 | .right {
20 | background: var(--bg-forth);
21 | color: var(--color-secondary);
22 | height: 38px;
23 | flex: 1 1;
24 | border-radius: 50px;
25 | font-size: 15px;
26 | line-height: 21px;
27 | display: flex;
28 | align-items: center;
29 | padding: 0 10px;
30 | display: flex;
31 | justify-content: space-between;
32 | align-items: center;
33 | gap: 10px;
34 | }
35 | .right:hover {
36 | background: var(--bg-third);
37 | }
38 | .input {
39 | width: 100%;
40 | height: 100%;
41 | }
42 | .input input {
43 | outline: none;
44 | border: none;
45 | background: transparent;
46 | width: 100%;
47 | height: 100%;
48 | font-size: 14px;
49 | padding-left: 5px;
50 | }
51 | .emoji_picker {
52 | z-index: 1;
53 | }
54 | .emoji_wrap {
55 | display: flex;
56 | gap: 15px;
57 | }
58 |
59 | .camera {
60 | display: flex;
61 | align-items: center;
62 | justify-content: center;
63 | }
64 | .camera i {
65 | transform: scale(1.3);
66 | cursor: pointer;
67 | }
68 | .emoji i {
69 | margin-top: 6px;
70 | }
71 | .img_perview {
72 | position: relative;
73 | width: max-content;
74 | margin: 16px 60px 10px;
75 | }
76 | .img_perview img {
77 | width: 150px;
78 | height: 100px;
79 | object-fit: cover;
80 | border-radius: 10px;
81 | box-shadow: 0 4px 10px 0 var(--shadow-2);
82 | border: 1px solid var(--divider);
83 | }
84 | .img_perview .exit {
85 | cursor: pointer;
86 | display: flex;
87 | align-items: center;
88 | justify-content: center;
89 | background: white;
90 | padding: 4px;
91 | border-radius: 50px;
92 | border: 1px solid var(--divider);
93 | position: absolute;
94 | top: -15px;
95 | right: -15px;
96 | }
97 |
--------------------------------------------------------------------------------
/src/pages/profile/Friends.jsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import { Link } from "react-router-dom";
3 | import Card from "../../components/UI/Card/Card";
4 | import classes from "./style.module.css";
5 | import PuffLoader from "react-spinners/PuffLoader";
6 | import Skeleton from "react-loading-skeleton";
7 |
8 | function Friends({ userData, userFriends, photosSkelton }) {
9 | return (
10 |
11 |
12 | Friends
13 |
14 | See all Friends
15 |
16 |
17 |
18 |
19 | {photosSkelton ? (
20 |
21 | ) : (
22 | `${userData?.friendsCount} Friends`
23 | )}
24 |
25 | {photosSkelton ? (
26 |
29 | ) : (
30 |
31 | {userFriends &&
32 | userFriends.slice(0, 9).map((user, i) => (
33 |
34 |
38 |
39 | {user.first_name} {user.last_name}{" "}
40 | {user?.confirmed && (
41 |
45 | )}
46 |
47 |
48 | ))}
49 |
50 | )}
51 |
52 |
53 | );
54 | }
55 |
56 | export default Friends;
57 |
--------------------------------------------------------------------------------
/src/components/login/GenderSelector.jsx:
--------------------------------------------------------------------------------
1 | import React, { useState } from "react";
2 | import styles from "./SignupForm.module.css";
3 | import { Field, ErrorMessage, useField } from "formik";
4 |
5 | import { useMediaQuery } from "react-responsive";
6 | import Popper from "../Popper/Popper";
7 |
8 | export default function GenderSelector({ handleSignupChange, x, disabled }) {
9 | const [trigger, setTrigger] = useState(null);
10 | const [show, setShow] = useState(false);
11 | const [field, meta] = useField({ name: "gender" });
12 | const genderError = meta.error;
13 |
14 | const desktopView = useMediaQuery({
15 | query: "(min-width: 850px)",
16 | });
17 |
18 | return (
19 | setShow(true)}
23 | onMouseLeave={() => setShow(false)}
24 | >
25 |
26 | Gender{" "}
27 | {genderError ? (
28 |
29 | ) : (
30 |
31 | )}
32 |
33 |
34 |
44 |
54 | {genderError && show && (
55 |
60 |
61 |
62 | )}
63 |
64 |
65 | );
66 | }
67 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "backbook",
3 | "version": "0.1.0",
4 | "private": true,
5 | "dependencies": {
6 | "@popperjs/core": "^2.11.6",
7 | "@reduxjs/toolkit": "^1.9.1",
8 | "@tanstack/react-query": "^4.19.1",
9 | "@testing-library/jest-dom": "^5.14.1",
10 | "@testing-library/react": "^13.0.0",
11 | "@testing-library/user-event": "^13.2.1",
12 | "axios": "^1.2.1",
13 | "emoji-picker-react": "^4.4.7",
14 | "file-saver": "^2.0.5",
15 | "firebase": "^9.15.0",
16 | "formik": "^2.2.9",
17 | "js-cookie": "^3.0.1",
18 | "moment": "^2.29.4",
19 | "react": "^18.2.0",
20 | "react-copy-to-clipboard": "^5.1.0",
21 | "react-dom": "^18.2.0",
22 | "react-easy-crop": "^4.6.3",
23 | "react-hot-toast": "^2.4.0",
24 | "react-icons": "^4.7.1",
25 | "react-indiana-drag-scroll": "^3.0.3-alpha",
26 | "react-intersection-observer": "^9.4.1",
27 | "react-loading-skeleton": "^3.1.0",
28 | "react-lottie-player": "^1.5.4",
29 | "react-moment": "^1.1.2",
30 | "react-popper": "^2.3.0",
31 | "react-redux": "^8.0.5",
32 | "react-responsive": "^9.0.2",
33 | "react-router-dom": "^6.4.4",
34 | "react-scripts": "^5.0.1",
35 | "react-simple-image-viewer": "^1.2.2",
36 | "react-spinners": "^0.13.7",
37 | "redux": "^4.2.0",
38 | "socket.io-client": "^4.5.4",
39 | "styled-components": "^5.3.6",
40 | "web-vitals": "^2.1.0",
41 | "yup": "^0.32.11"
42 | },
43 | "scripts": {
44 | "start": "react-scripts start",
45 | "build": "react-scripts build",
46 | "test": "react-scripts test",
47 | "eject": "react-scripts eject"
48 | },
49 | "eslintConfig": {
50 | "extends": [
51 | "react-app",
52 | "react-app/jest"
53 | ]
54 | },
55 | "browserslist": {
56 | "production": [
57 | ">0.2%",
58 | "not dead",
59 | "not op_mini all"
60 | ],
61 | "development": [
62 | "last 1 chrome version",
63 | "last 1 firefox version",
64 | "last 1 safari version"
65 | ]
66 | },
67 | "engines": {
68 | "node": ">=16.0.0"
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/public/reacts/haha.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/components/Popper/Popper.jsx:
--------------------------------------------------------------------------------
1 | import React, { useState } from "react";
2 | import styled from "styled-components";
3 | import { usePopper } from "react-popper";
4 | import Portal from "../../utils/Portal";
5 |
6 | export const TooltipArrow = styled.div`
7 | width: 0.6rem;
8 | height: 0.6rem;
9 | &::before {
10 | content: "";
11 | background: #b94a48;
12 | width: 0.6rem;
13 | height: 0.6rem;
14 | transform: translate(-50%, -50%) rotate(45deg);
15 | position: absolute;
16 | top: 0;
17 | left: 0;
18 | }
19 | `;
20 |
21 | const TipWrapper = styled.div`
22 | background: #b94a48;
23 | border-radius: 5px;
24 | color: white;
25 | padding: 0.8rem;
26 | font-weight: 300;
27 | font-size: 13px;
28 | z-index: 99;
29 | max-width: 318px;
30 |
31 | &[data-popper-placement^="right"] {
32 | ${TooltipArrow} {
33 | left: 0px;
34 | }
35 | }
36 |
37 | &[data-popper-placement^="left"] {
38 | ${TooltipArrow} {
39 | right: -0.6rem;
40 | }
41 | }
42 |
43 | &[data-popper-placement^="top"] {
44 | ${TooltipArrow} {
45 | bottom: -0.6rem;
46 | }
47 | }
48 |
49 | &[data-popper-placement^="bottom"] {
50 | ${TooltipArrow} {
51 | top: 0px;
52 | }
53 | }
54 | `;
55 |
56 | const Popper = ({ children, trigger, placement, offsetNum }) => {
57 | const [popperElement, setPopperElement] = useState(null);
58 | const [arrowElement, setArrowElement] = useState(null);
59 |
60 | const { styles, attributes } = usePopper(trigger, popperElement, {
61 | placement,
62 | modifiers: [
63 | { name: "arrow", options: { element: arrowElement } },
64 | {
65 | name: "offset",
66 | options: {
67 | offset: [0, parseInt(offsetNum || 8)],
68 | },
69 | },
70 | ],
71 | });
72 |
73 | return (
74 |
75 |
80 | {children}
81 |
82 |
83 |
84 | );
85 | };
86 |
87 | export default Popper;
88 |
--------------------------------------------------------------------------------
/src/components/UI/Notification/Notification.jsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import Moment from "react-moment";
3 | import { useNavigate } from "react-router-dom";
4 | import styles from "./Notification.module.css";
5 |
6 | function Notification({ toast, t, notification }) {
7 | const navigate = useNavigate();
8 | return (
9 |
10 |
11 |
New notification
12 |
toast.dismiss(t.id)}
14 | className="small_circle"
15 | style={{
16 | width: "25px",
17 | height: "25px",
18 | margin: "0",
19 | }}
20 | >
21 |
27 |
28 |
29 |
{
32 | toast.dismiss(t.id);
33 | navigate(notification.click);
34 | }}
35 | >
36 |
37 |

38 |

47 |
48 |
49 | {notification.content}
50 |
51 |
52 | {notification.createdAt}
53 |
54 |
55 |
56 |
66 |
67 |
68 | );
69 | }
70 |
71 | export default Notification;
72 |
--------------------------------------------------------------------------------
/src/components/messages/createGroup/CreateGroup.module.css:
--------------------------------------------------------------------------------
1 | .wrap {
2 | display: flex;
3 | justify-content: center;
4 | align-items: center;
5 | }
6 |
7 | .card {
8 | width: 97%;
9 | max-width: 500px;
10 | padding: 0 !important;
11 | margin: 0 6px;
12 | box-shadow: 0 6px 28px 0 var(--shadow-2), 0 2px 4px 0 var(--shadow-1),
13 | inset 0 0 0 1px var(--shadow-inset) !important;
14 | }
15 | .header {
16 | display: flex;
17 | justify-content: center;
18 | align-items: center;
19 | height: 60px;
20 | border-bottom: 1px solid var(--divider);
21 | position: relative;
22 | }
23 | .header span {
24 | font-size: 18px;
25 | font-weight: 700;
26 | }
27 | .exit {
28 | position: absolute;
29 | right: 5px;
30 | }
31 | .content {
32 | padding: 15px;
33 | }
34 | /***************************/
35 | .input_wrap {
36 | width: 100%;
37 | position: relative;
38 | }
39 | .input_wrap input {
40 | background: var(--bg-primary);
41 | border: 1px solid var(--bg-third);
42 | border-radius: 10px;
43 | color: var(--color-primary);
44 | font-size: 17px;
45 | height: 50px;
46 | margin-bottom: 10px;
47 | outline: none;
48 | padding-left: 10px;
49 | width: 100%;
50 | }
51 | .error {
52 | border-color: #b94a48 !important;
53 | }
54 | .input_wrap i {
55 | position: absolute;
56 | right: 5px;
57 | top: 15px;
58 | -webkit-transform: scale(0.8);
59 | transform: scale(0.8);
60 | }
61 | .label {
62 | font-size: 14px;
63 | font-weight: 400;
64 | color: var(--color-secondary);
65 | margin: 4px 0;
66 | }
67 | /****************************/
68 |
69 | .members {
70 | display: flex;
71 | flex-wrap: wrap;
72 | margin: 8px 0;
73 | gap: 8px;
74 | max-height: 250px;
75 | overflow: auto;
76 | }
77 |
78 | .member {
79 | background: var(--blue-color);
80 | color: #fff;
81 | padding: 4px 8px;
82 | border-radius: 6px;
83 | font-size: 13px;
84 | display: flex;
85 | align-items: center;
86 | justify-content: center;
87 | gap: 4px;
88 | position: relative;
89 | margin-left: 15px;
90 | padding-left: 20px;
91 | }
92 | .member img {
93 | position: absolute;
94 | left: -15px;
95 | width: 32px;
96 | border-radius: 100%;
97 | border: 4px solid var(--blue-color);
98 | }
99 |
--------------------------------------------------------------------------------
/src/components/home/posts/CreatePost/CreatePost.module.css:
--------------------------------------------------------------------------------
1 | .create_post {
2 | width: 100%;
3 | background: var(--bg-primary);
4 | border-radius: 10px;
5 | box-shadow: 0 1px 2px var(--shadow-1);
6 | cursor: pointer;
7 | }
8 | .header {
9 | display: flex;
10 | align-items: center;
11 | gap: 8px;
12 | padding: 10px 17px 5px 15px;
13 | }
14 |
15 | .header img {
16 | width: 40px;
17 | height: 40px;
18 | border-radius: 50%;
19 | object-fit: cover;
20 | }
21 | .open_post {
22 | background: var(--bg-forth);
23 | color: var(--color-secondary);
24 | height: 41px;
25 | flex: 1;
26 | border-radius: 50px;
27 | font-size: 17px;
28 | line-height: 21px;
29 | display: flex;
30 | align-items: center;
31 | padding-left: 10px;
32 | -webkit-line-clamp: 1;
33 | -webkit-box-orient: horizontal;
34 | overflow: hidden;
35 | line-height: 2rem;
36 | }
37 | .splitter {
38 | height: 1px;
39 | width: 95%;
40 | background: var(--bg-third);
41 | margin: 7px 10px;
42 | }
43 |
44 | .post_body {
45 | padding: 0 10px 8px 10px;
46 | display: grid;
47 | grid-template-columns: repeat(3, 1fr);
48 | }
49 |
50 | .createPost_icon {
51 | display: flex;
52 | align-items: center;
53 | justify-content: center;
54 | gap: 8px;
55 | font-weight: 600;
56 | padding: 7px;
57 | color: var(--color-secondary);
58 | border-radius: 10px;
59 | font-size: 14px;
60 | }
61 | @media (max-width: 1175px) {
62 | .create_post {
63 | width: 84%;
64 | }
65 | }
66 | @media (max-width: 1030px) {
67 | .create_post {
68 | width: 100%;
69 | }
70 | }
71 | @media (max-width: 960px) {
72 | .create_post {
73 | width: 93%;
74 | }
75 | }
76 |
77 | @media (max-width: 885px) {
78 | .create_post {
79 | width: 100%;
80 | }
81 | }
82 |
83 | @media (max-width: 620px) {
84 | .create_post {
85 | width: 100%;
86 | }
87 | }
88 | @media (max-width: 400px) {
89 | .create_post {
90 | width: 100%;
91 | }
92 |
93 | .post_body {
94 | padding: 5px;
95 | }
96 | .createPost_icon {
97 | gap: 4px;
98 | padding: 5px;
99 | font-size: 12px;
100 | }
101 | .createPost_icon svg {
102 | width: 20px;
103 | height: 20px;
104 | }
105 | }
106 |
--------------------------------------------------------------------------------
/src/components/profile/cover/Cover.module.css:
--------------------------------------------------------------------------------
1 | .cover {
2 | width: 100%;
3 | padding: 18%;
4 | background: var(--bg-third);
5 | border-radius: 0 0 10px 10px;
6 | position: relative;
7 | min-height: 170px;
8 | background-size: cover;
9 | background-position: center;
10 | }
11 | .edit_cover_wrapper {
12 | position: absolute;
13 | right: 20px;
14 | bottom: 20px;
15 | }
16 | .edit_cover {
17 | background: var(--bg-third);
18 | padding: 7px 15px;
19 | display: flex;
20 | align-items: center;
21 | gap: 10px;
22 | font-weight: 600;
23 | font-size: 14px;
24 | color: #111;
25 | border-radius: 10px;
26 | cursor: pointer;
27 | width: max-content;
28 | position: relative;
29 | }
30 | .edit_cover i {
31 | transform: scale(0.9);
32 | margin-top: 4px;
33 | }
34 | .edit_cover span {
35 | display: none;
36 | }
37 | .cover_upload_menu {
38 | position: absolute;
39 | right: 50%;
40 | top: 41px;
41 | padding: 10px;
42 | z-index: 8;
43 | width: 250px;
44 | }
45 | .open_cover_menu_item {
46 | display: flex;
47 | align-items: center;
48 | gap: 10px;
49 | padding: 10px;
50 | cursor: pointer;
51 | font-weight: 600;
52 | font-size: 14px;
53 | border-radius: 10px;
54 | }
55 | .cover_cropper {
56 | width: 100%;
57 | height: 100%;
58 | }
59 | .mediaClassName {
60 | width: 100%;
61 | }
62 |
63 | .save_cover {
64 | position: fixed;
65 | left: 0;
66 | top: 56px;
67 | height: 56px;
68 | width: 100%;
69 | background: rgb(0 0 0 / 70%);
70 | z-index: 1;
71 | display: flex;
72 | align-items: center;
73 | justify-content: space-between;
74 | padding: 0 20px;
75 | }
76 | .btns {
77 | display: flex;
78 | justify-content: flex-end;
79 | gap: 10px;
80 | }
81 |
82 | .btns button {
83 | font-weight: 500;
84 | }
85 |
86 | .save_cover .left {
87 | display: flex;
88 | align-items: center;
89 | gap: 10px;
90 | color: #fff;
91 | }
92 |
93 | .save_cover .left i {
94 | filter: invert(100%);
95 | }
96 |
97 | @media (min-width: 900px) {
98 | .edit_cover span {
99 | display: inline;
100 | }
101 | }
102 |
103 | :global(.dark) .cover i {
104 | filter: invert(100%);
105 | }
106 |
107 | :global(.dark) .cover {
108 | background-color: #2d2d2d;
109 | }
110 |
--------------------------------------------------------------------------------
/public/icons/facebook.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/src/components/posts/post/shares/ShareMenu.jsx:
--------------------------------------------------------------------------------
1 | import React, { useRef, useState } from "react";
2 | import useOnClickOutside from "../../../../hooks/useOnClickOutside";
3 | import Card from "../../../UI/Card/Card";
4 | import MenuItem from "../MenuItem";
5 | import classes from "../Post.module.css";
6 | import { IoIosLink } from "react-icons/io";
7 | import { CopyToClipboard } from "react-copy-to-clipboard";
8 | import toast from "react-hot-toast";
9 | import CreateSharePost from "./CreateSharePost";
10 |
11 | function ShareMenu({
12 | showMenu,
13 | setShowMenu,
14 | post,
15 | user,
16 | postRef,
17 | setSharesCount,
18 | }) {
19 | const menuRef = useRef();
20 |
21 | const [showSharePost, setShowSharePost] = useState(false);
22 |
23 | useOnClickOutside(menuRef, showMenu, () => {
24 | if (showSharePost) return;
25 | setShowMenu(false);
26 | });
27 |
28 | const full = `${window.location.origin}/${post.user.username}/posts/${post._id}`;
29 |
30 | return (
31 |
36 |
64 | {showSharePost && (
65 |
71 | )}
72 |
73 | );
74 | }
75 |
76 | export default ShareMenu;
77 |
--------------------------------------------------------------------------------
/src/components/profile/cover/OldCovers.jsx:
--------------------------------------------------------------------------------
1 | import React, { useRef } from "react";
2 | import useOnClickOutside from "../../../hooks/useOnClickOutside";
3 | import Card from "../../UI/Card/Card";
4 | import classes from "./OldCovers.module.css";
5 |
6 | function OldCovers({ setShowOldCover, setImage, photosData, showOldCover }) {
7 | const oldCoversCardRef = useRef(null);
8 |
9 | useOnClickOutside(oldCoversCardRef, showOldCover, () => {
10 | setShowOldCover(false);
11 | });
12 |
13 | return (
14 |
15 |
16 |
17 | Update Cover Photo
18 |
setShowOldCover(false)}>
19 |
20 |
21 |
22 |
23 | {photosData?.profileCovers.length > 0 && (
24 | <>
25 |
Choose from old cover picture
26 |
27 | {photosData?.profileCovers.map((photo) => (
28 |

{
32 | setImage(photo.url);
33 | setShowOldCover(false);
34 | }}
35 | key={photo.id}
36 | />
37 | ))}
38 |
39 | >
40 | )}
41 | {photosData?.resources.length > 0 && (
42 | <>
43 |
Choose from your profile photos
44 |
45 | {photosData?.resources.map((photo) => (
46 |

{
50 | setImage(photo.url);
51 | setShowOldCover(false);
52 | }}
53 | key={photo.id}
54 | />
55 | ))}
56 |
57 | >
58 | )}
59 |
60 |
61 |
62 | );
63 | }
64 |
65 | export default OldCovers;
66 |
--------------------------------------------------------------------------------
/src/components/home/SendVerification/SendVerification.jsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import Card from "../../UI/Card/Card";
3 | import styles from "./SendVerification.module.css";
4 | import { useQuery } from "@tanstack/react-query";
5 | import axios from "axios";
6 | import Lottie from "react-lottie-player";
7 | import successAnimation from "../../UI/Lottie/success.json";
8 | import BarLoader from "react-spinners/BarLoader";
9 |
10 | function SendVerification() {
11 | const enabled = false;
12 | const { fetchStatus, status, error, data, refetch } = useQuery({
13 | queryKey: ["resendEmail"],
14 | queryFn: async () => {
15 | const { data } = await axios.post(
16 | `${process.env.REACT_APP_BACKEND_URL}/api/v1/users/resendEmailVerifivation`,
17 | {},
18 | {
19 | withCredentials: true,
20 | }
21 | );
22 | return data;
23 | },
24 | enabled,
25 | retry: false,
26 | });
27 |
28 | const resendEmail = () => {
29 | refetch();
30 | };
31 |
32 | if (data?.status === "success")
33 | return (
34 |
35 | Email verification sent successfully
36 |
37 |
47 |
48 | );
49 |
50 | if (fetchStatus === "fetching" && status === "loading")
51 | return (
52 |
53 |
59 |
60 | );
61 |
62 | return (
63 |
64 |
65 | Your account is not verified, verify your account to avoid deleting Your
66 | acccount.
67 |
68 |
69 | Resend email verification
70 |
71 | {error ? (
72 | {error.response?.data?.message}
73 | ) : (
74 | ""
75 | )}
76 |
77 | );
78 | }
79 |
80 | export default SendVerification;
81 |
--------------------------------------------------------------------------------
/src/components/login/LoginFooter.jsx:
--------------------------------------------------------------------------------
1 | import { Link } from "react-router-dom";
2 | import styles from "./LoginFooter.module.css";
3 |
4 | export default function LoginFooter() {
5 | return (
6 |
63 | );
64 | }
65 |
--------------------------------------------------------------------------------
/src/pages/messages/index.jsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import styles from "./messages.module.css";
3 | import { useParams } from "react-router-dom";
4 | import Middle from "./Middle";
5 | import Left from "./Left";
6 | import { useDispatch, useSelector } from "react-redux";
7 | import { useMediaQuery } from "react-responsive";
8 | import { useState } from "react";
9 | import { useEffect } from "react";
10 | import Lottie from "react-lottie-player";
11 | import homeDesk from "../../components/UI/Lottie/messages.json";
12 | import { setSelectedChat } from "../../app/slices/soketSlice";
13 |
14 | function Messages() {
15 | const { soketSlice, user: userState } = useSelector((state) => ({
16 | ...state,
17 | }));
18 | const dispatch = useDispatch();
19 |
20 | const user = userState.userinfo;
21 | const { chatId } = useParams();
22 | const desktopView = useMediaQuery({
23 | query: "(min-width: 850px)",
24 | });
25 |
26 | const pView = desktopView || !chatId;
27 |
28 | const [openInfo, setOpenInfo] = useState(pView);
29 |
30 | useEffect(() => {
31 | setOpenInfo(pView);
32 | }, [pView]);
33 |
34 | useEffect(() => {
35 | dispatch(setSelectedChat(chatId));
36 | }, [chatId]);
37 |
38 | useEffect(() => {
39 | const appHeight = (e) => {
40 | const doc = document.documentElement;
41 | const h = window.visualViewport.height;
42 | doc.style.setProperty("--app-height", `${h}px`);
43 | };
44 | window.addEventListener("resize", appHeight);
45 | appHeight();
46 |
47 | return () => {
48 | window.addEventListener("resize", appHeight);
49 | };
50 | }, []);
51 |
52 | return (
53 |
58 | {pView &&
}
59 | {chatId ? (
60 |
68 | ) : (
69 |
70 |
79 |
Start a conversation
80 |
81 | )}
82 |
83 | );
84 | }
85 |
86 | export default Messages;
87 |
--------------------------------------------------------------------------------
/src/components/forgot/SendEmail.jsx:
--------------------------------------------------------------------------------
1 | import { useState } from "react";
2 | import Card from "../UI/Card/Card";
3 | import styles from "./style.module.css";
4 | import axios from "axios";
5 | import FormLoader from "../FormLoader";
6 |
7 | function SendEmail({ setVisible, userInfos }) {
8 | const [error, setError] = useState("");
9 | const [loading, setLoading] = useState(false);
10 |
11 | const submitHandler = async () => {
12 | try {
13 | setLoading(true);
14 | await axios.post(
15 | `${process.env.REACT_APP_BACKEND_URL}/api/v1/users/forgotPassword`,
16 | {
17 | email: userInfos.email,
18 | },
19 | {
20 | withCredentials: true,
21 | }
22 | );
23 | setError("");
24 | setLoading(false);
25 | setVisible(2);
26 | } catch (error) {
27 | setError(error.response?.data?.message);
28 | setTimeout(() => {
29 | setLoading(false);
30 | }, 1000);
31 | }
32 | };
33 |
34 | return (
35 |
36 | Reset Your Password
37 | {error ? (
38 |
39 |
Error
40 |
{error}
41 |
42 | ) : (
43 | ""
44 | )}
45 |
46 |
47 |
48 |
49 |
50 | How do you want to receive the code to reset your password?
51 |
52 |
59 |
60 |
61 |

62 |
{userInfos.email}
63 |
{userInfos.first_name}
64 |
65 |
66 |
67 |
68 |
71 |
74 |
75 |
76 | );
77 | }
78 |
79 | export default SendEmail;
80 |
--------------------------------------------------------------------------------
/src/components/posts/post/comments/Comments.jsx:
--------------------------------------------------------------------------------
1 | import { useInfiniteQuery } from "@tanstack/react-query";
2 | import { useState, useEffect } from "react";
3 |
4 | import classes from "./Comments.module.css";
5 | import axios from "axios";
6 | import Comment from "./Comment";
7 |
8 | function Comments({
9 | lastComment,
10 | commentsCount,
11 | postID,
12 | lastCommentData,
13 | commentRef,
14 | }) {
15 | const [comments, setComments] = useState([]);
16 |
17 | const fetchProjects = async ({ pageParam = 1 }) => {
18 | const { data } = await axios.get(
19 | `${process.env.REACT_APP_BACKEND_URL}/api/v1/posts/comments/${postID}?limit=4&page=${pageParam}&sort=-createdAt`,
20 | {
21 | withCredentials: true,
22 | }
23 | );
24 | return data;
25 | };
26 |
27 | const { fetchNextPage, isFetching } = useInfiniteQuery({
28 | queryKey: ["comments", postID],
29 | queryFn: fetchProjects,
30 | getNextPageParam: (lastPage, pages) => {
31 | if (lastPage.datalength < 4) {
32 | return undefined;
33 | } else {
34 | return pages.length + 1;
35 | }
36 | },
37 | onSuccess: (data) => {
38 | const newCommemnts = data.pages[data.pages.length - 1].data.comments;
39 | if (data.pages.length === 1) {
40 | setComments([...newCommemnts]);
41 | } else {
42 | setComments((prev) => [...prev, ...newCommemnts]);
43 | }
44 | },
45 | enabled: false,
46 | });
47 |
48 | const viewMoreHandler = () => {
49 | fetchNextPage();
50 | };
51 |
52 | useEffect(() => {
53 | if (lastComment) {
54 | setComments((prev) => [...prev, lastComment]);
55 | }
56 | }, []);
57 |
58 | useEffect(() => {
59 | if (lastCommentData) setComments((prev) => [lastCommentData, ...prev]);
60 | }, [lastCommentData]);
61 |
62 | return (
63 |
64 | {comments.map((comment) => (
65 |
66 | ))}
67 | {commentsCount > comments.length ? (
68 | <>
69 |
70 | View more comments
71 | {isFetching && " Loading..."}
72 |
73 | >
74 | ) : (
75 | <>
76 |
{
79 | commentRef.current.focus();
80 | }}
81 | >
82 | Write a comment...
83 |
84 | >
85 | )}
86 |
87 | );
88 | }
89 |
90 | export default Comments;
91 |
--------------------------------------------------------------------------------
/src/components/home/right/HomeRight.module.css:
--------------------------------------------------------------------------------
1 | .right_home {
2 | position: fixed;
3 | right: 20px;
4 | top: 4rem;
5 | width: 21vw;
6 | }
7 |
8 | .heading {
9 | font-size: 16px;
10 | font-weight: 600;
11 | color: var(--color-secondary);
12 | padding: 13px 10px 11px 10px;
13 | }
14 |
15 | .splitter {
16 | height: 1.3px;
17 | background: var(--divider);
18 | width: 21vw;
19 | margin: 6px 2px 0 12px;
20 | }
21 |
22 | .contacts_header {
23 | position: relative;
24 | display: flex;
25 | align-items: center;
26 | justify-content: space-between;
27 | padding: 12px 0 7px 10px;
28 | font-weight: 600;
29 | color: var(--color-secondary);
30 | }
31 |
32 | .contacts_header_right {
33 | display: flex;
34 | align-items: center;
35 | gap: 6px;
36 | position: absolute;
37 | right: -9px;
38 | top: 7px;
39 | }
40 |
41 | .contact_circle {
42 | width: 35px;
43 | height: 35px;
44 | border-radius: 50%;
45 | display: flex;
46 | align-items: center;
47 | justify-content: center;
48 | cursor: pointer;
49 | }
50 |
51 | .contact_circle:nth-child(1) {
52 | margin-right: -1px;
53 | }
54 |
55 | .contact_circle:nth-child(2) {
56 | margin-right: 1px;
57 | }
58 |
59 | .contact_circle:nth-child(3) {
60 | margin-top: -1px;
61 | }
62 |
63 | .contacts_list {
64 | padding: 5px;
65 | }
66 |
67 | .contact {
68 | display: flex;
69 | align-items: center;
70 | gap: 12px;
71 | font-size: 14px;
72 | padding: 5px;
73 | border-radius: 10px;
74 | cursor: pointer;
75 | color: var(--color-primary);
76 | font-weight: 600;
77 | }
78 |
79 | .contact_img img {
80 | width: 36px;
81 | height: 36px;
82 | border-radius: 50%;
83 | object-fit: cover;
84 | }
85 |
86 | .contact span {
87 | transform: translateY(-5px);
88 | }
89 |
90 | @media (max-width: 1175px) {
91 | .right_home {
92 | width: 18vw;
93 | }
94 | }
95 |
96 | @media (max-width: 1030px) {
97 | .right_home {
98 | width: 20vw;
99 | }
100 |
101 | .contacts_header_right {
102 | right: 10%;
103 | }
104 |
105 | .contact_circle {
106 | width: 20px;
107 | }
108 | }
109 | @media (max-width: 1030px) {
110 | .right_home {
111 | width: 20vw;
112 | }
113 | }
114 | @media (max-width: 960px) {
115 | .right_home {
116 | width: 25vw;
117 | }
118 |
119 | .splitter1 {
120 | width: 25vw;
121 | }
122 |
123 | .contact_circle {
124 | width: 30px;
125 | }
126 |
127 | .contacts_header_right {
128 | right: 0;
129 | }
130 | }
131 |
132 | @media (max-width: 885px) {
133 | .right_home {
134 | display: none;
135 | }
136 | }
137 |
--------------------------------------------------------------------------------
/src/components/messages/SearchUser.module.css:
--------------------------------------------------------------------------------
1 | /*---Search menu-----*/
2 | .search_area {
3 | position: absolute;
4 | align-items: flex-start;
5 | flex-direction: column;
6 | gap: 6px;
7 | background: var(--bg-primary);
8 | box-shadow: 0 12px 12px var(--shadow-1), inset 0 0 0 0 var(--shadow-inset);
9 | transition: all 0.2s;
10 | -webkit-font-smoothing: antialiased;
11 | z-index: 1;
12 | padding: 8px 6px 10px 6px;
13 | overflow: hidden;
14 | height: -webkit-fill-available;
15 | width: 100%;
16 | top: 48px;
17 | }
18 |
19 | .search_wrap {
20 | display: flex;
21 | align-items: center;
22 | }
23 |
24 | .search {
25 | display: flex;
26 | align-items: center;
27 | gap: 6px;
28 | background: var(--bg-forth);
29 | padding: 7px 20px 7px 13px;
30 | border-radius: 50px;
31 | cursor: text;
32 | width: 100%;
33 | min-width: 233px;
34 | }
35 | .input {
36 | outline: none;
37 | border: none;
38 | background: transparent;
39 | font-size: 15px;
40 | font-family: inherit;
41 | padding-left: 2px;
42 | width: 100%;
43 | }
44 | .search_area .search svg {
45 | transform: translateY(1px);
46 | }
47 |
48 | .input::placeholder {
49 | transform: translateY(-2px);
50 | }
51 |
52 | .input:focus::placeholder {
53 | transform: translateY(-1px);
54 | }
55 |
56 | .search_history {
57 | width: 100%;
58 | }
59 |
60 | .search_history_header {
61 | width: 100%;
62 | display: flex;
63 | align-items: center;
64 | justify-content: space-between;
65 | padding: 10px;
66 | font-size: 14px;
67 | }
68 |
69 | .search_history_header span {
70 | font-weight: 600;
71 | font-size: 16px;
72 | }
73 |
74 | .search_history_header a {
75 | cursor: pointer;
76 | color: var(--blue-color);
77 | }
78 |
79 | /*---Search menu-----*/
80 |
81 | .search_results {
82 | display: flex;
83 | flex-direction: column;
84 | gap: 5px;
85 | }
86 | .search_result {
87 | display: flex;
88 | align-items: center;
89 | gap: 12px;
90 | font-size: 14px;
91 | padding: 5px;
92 | border-radius: 10px;
93 | cursor: pointer;
94 | color: var(--color-primary);
95 | font-weight: 600;
96 | }
97 |
98 | .search_result_img {
99 | width: 36px;
100 | height: 36px;
101 | border-radius: 50%;
102 | object-fit: cover;
103 | }
104 |
105 | .search_result span {
106 | transform: translateY(-5px);
107 | }
108 |
109 | .search_item {
110 | border-radius: 10px;
111 | padding: 2px 5px;
112 | }
113 | .search_user_item {
114 | display: flex;
115 | align-items: center;
116 | width: 100%;
117 | justify-content: space-between;
118 | padding-right: 10px;
119 | }
120 |
--------------------------------------------------------------------------------
/src/components/login/SignupForm.module.css:
--------------------------------------------------------------------------------
1 | .signup {
2 | position: absolute;
3 | left: 50%;
4 | top: 50%;
5 | -webkit-transform: translate(-50%, -50%);
6 | transform: translate(-50%, -50%);
7 | z-index: 10;
8 | width: 350px;
9 | box-shadow: 0 2px 4px var(--shadow-1);
10 | }
11 | .signup_header {
12 | border-bottom: 1px solid var(--bg-third);
13 | display: flex;
14 | flex-direction: column;
15 | gap: 10px;
16 | padding-bottom: 10px;
17 | position: relative;
18 | margin-bottom: 10px;
19 | }
20 | .signup_header i {
21 | cursor: pointer;
22 | position: absolute;
23 | right: 0;
24 | }
25 | .signup_header span:first-of-type {
26 | font-size: 32px;
27 | font-weight: 700;
28 | }
29 | .signup_header span:last-of-type {
30 | color: var(--color-secondary);
31 | font-size: 15px;
32 | }
33 | .line {
34 | display: flex;
35 | gap: 10px;
36 | }
37 | .col {
38 | margin-bottom: 10px;
39 | }
40 | .colHeader {
41 | align-items: center;
42 | color: var(--color-secondary);
43 | display: flex;
44 | font-size: 13px;
45 | gap: 4px;
46 | }
47 | .colHeader i {
48 | margin-top: 3px;
49 | }
50 | .colHeader .error_icon {
51 | margin-top: 30px;
52 | }
53 | .grid {
54 | grid-gap: 10px;
55 | display: grid;
56 | gap: 10px;
57 | grid-template-columns: repeat(3, 1fr);
58 | height: 35px;
59 | margin-top: 5px;
60 | width: 100%;
61 | }
62 | .gender {
63 | grid-template-columns: repeat(2, 1fr);
64 | }
65 | .grid select {
66 | border-radius: 5px;
67 | color: var(--color-primary);
68 | cursor: pointer;
69 | font-size: 16px;
70 | width: 100%;
71 | padding: 0 10px;
72 | background: var(--bg-primary);
73 | }
74 | .grid label {
75 | border-radius: 5px;
76 | align-items: center;
77 | border: 1px solid var(--color-secondary);
78 | display: flex;
79 | justify-content: space-between;
80 | padding: 0 15px;
81 | }
82 | .err_icon {
83 | transform: scale(0.6);
84 | }
85 | .info {
86 | color: var(--color-secondary);
87 | font-size: 11px;
88 | margin-top: 10px;
89 | }
90 | .info span {
91 | color: var(--blue);
92 | cursor: pointer;
93 | }
94 | .info span:hover {
95 | text-decoration: underline;
96 | }
97 | .btn_wrap {
98 | align-items: center;
99 | display: flex;
100 | justify-content: center;
101 | margin: 20px 0 10px;
102 | width: 100%;
103 | }
104 | .btn_wrap button {
105 | background: var(--green-color);
106 | font-size: 17px !important;
107 | font-weight: 600 !important;
108 | margin-top: 1rem;
109 | width: 70% !important;
110 | }
111 | @media (min-width: 539px) {
112 | .signup {
113 | width: 400px;
114 | }
115 | }
116 |
--------------------------------------------------------------------------------
/src/components/profile/intro/EditArea.jsx:
--------------------------------------------------------------------------------
1 | import { useRef, useEffect } from "react";
2 | import isRTL from "../../../utils/isRTL";
3 | import classes from "./intro.module.css";
4 |
5 | function EditArea({
6 | innerRef,
7 | infos,
8 | handleChange,
9 | setShow,
10 | max,
11 | remain,
12 | updateDetails,
13 | details,
14 | name,
15 | placeholder,
16 | rel,
17 | }) {
18 | const isChanged = rel ? false : details?.[name] === infos?.[name];
19 | const editAreaRef = useRef(null);
20 |
21 | useEffect(() => {
22 | editAreaRef.current.focus();
23 | }, []);
24 |
25 | return (
26 |
27 | {rel ? (
28 |
45 | ) : (
46 |
61 | )}
62 | {name === "bio" && (
63 |
{remain} characters remaining
64 | )}
65 |
66 |
69 |
83 |
84 |
85 | );
86 | }
87 |
88 | export default EditArea;
89 |
--------------------------------------------------------------------------------
/public/icons/backbook.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
29 |
--------------------------------------------------------------------------------