├── .DS_Store
├── .env.example
├── .github
├── FUNDING.yml
├── ISSUE_TEMPLATE
│ ├── bug_report.md
│ └── feature_request.md
└── workflows
│ ├── greetings.yml
│ ├── node.js.yml
│ └── npm-publish.yml
├── .gitignore
├── CODE_OF_CONDUCT.md
├── CONTRIBUTE.md
├── Dockerfile
├── LICENSE
├── README.md
├── assets
├── CD.png
├── Readme.md
├── audio-room.png
├── chat-room.png
├── code-editor.png
├── codesync.png
├── compile-code.png
├── head.png
├── join.png
├── main.png
├── members.png
├── multi-theme.png
├── multi-theme2.png
├── text-editor.png
├── user-auth.png
└── white-board.png
├── client
├── .env.example
├── .gitignore
├── Dockerfile
├── README.md
├── craco.config.js
├── package-lock.json
├── package.json
├── public
│ ├── android-chrome-192x192.png
│ ├── android-chrome-512x512.png
│ ├── apple-touch-icon.png
│ ├── favicon-16x16.png
│ ├── favicon-32x32.png
│ ├── favicon.ico
│ ├── image
│ │ ├── Logos
│ │ │ ├── codesync-01.png
│ │ │ ├── logo-01.svg
│ │ │ ├── logo-02.svg
│ │ │ ├── pattern-01.png
│ │ │ ├── pattern-01.svg
│ │ │ ├── sample.png
│ │ │ ├── xyz.png
│ │ │ └── xyz2.png
│ │ ├── Team
│ │ │ ├── 1637646334769.png
│ │ │ ├── harsh.JPG
│ │ │ ├── jayraj.jpg
│ │ │ └── vivek.JPG
│ │ ├── codesynclogo.png
│ │ ├── email-pattern.png
│ │ ├── eraser.png
│ │ └── icons
│ │ │ ├── CodeSync-type-logo.png
│ │ │ ├── CodeSync-type-logo.svg
│ │ │ ├── CodeSync.svg
│ │ │ ├── chat-22.svg
│ │ │ ├── chat.svg
│ │ │ ├── close.svg
│ │ │ ├── code-room.svg
│ │ │ ├── coding.svg
│ │ │ ├── compiler.svg
│ │ │ ├── copy-svgrepo-com.svg
│ │ │ ├── copy.svg
│ │ │ ├── download.svg
│ │ │ ├── drawing-svgrepo.svg
│ │ │ ├── drawing.svg
│ │ │ ├── input.svg
│ │ │ ├── microphone-voice.svg
│ │ │ ├── mute.svg
│ │ │ ├── notes.svg
│ │ │ ├── pensil.svg
│ │ │ ├── send.svg
│ │ │ ├── share.svg
│ │ │ └── text-editor-repo.svg
│ ├── index.html
│ ├── link_icon.svg
│ ├── manifest.json
│ ├── robots.txt
│ └── site.webmanifest
├── src
│ ├── API.js
│ ├── Action
│ │ └── UserAction.js
│ ├── App.css
│ ├── App.js
│ ├── App.test.js
│ ├── BaseURL.js
│ ├── Components
│ │ ├── Auth
│ │ │ ├── ForgotPassword
│ │ │ │ └── ForgotPassword.js
│ │ │ ├── Login
│ │ │ │ ├── LoginPage.css
│ │ │ │ └── LoginPage.js
│ │ │ ├── Register
│ │ │ │ ├── Icon.js
│ │ │ │ └── Register.js
│ │ │ └── ResetPassword
│ │ │ │ └── ResetPassword.js
│ │ ├── Editor
│ │ │ └── Editor.js
│ │ ├── Error
│ │ │ └── NotFound.js
│ │ ├── FrontPage
│ │ │ ├── FrontPage.js
│ │ │ ├── Landing.css
│ │ │ └── LandingPage.js
│ │ ├── Header
│ │ │ ├── Header.css
│ │ │ └── Header.js
│ │ ├── HomePage
│ │ │ └── HomePage.js
│ │ ├── Input
│ │ │ └── Input.js
│ │ ├── Mobile
│ │ │ └── Mobile.js
│ │ ├── NotFound
│ │ │ └── NotFound.js
│ │ ├── Room
│ │ │ ├── CreateRoom.js
│ │ │ ├── DropDown
│ │ │ │ └── LanguageDP.js
│ │ │ ├── Email
│ │ │ │ └── Invite.js
│ │ │ ├── JoinRoom.js
│ │ │ ├── Language
│ │ │ │ └── Default.js
│ │ │ ├── Message
│ │ │ │ ├── Message.css
│ │ │ │ └── Message.js
│ │ │ ├── RichEditor
│ │ │ │ └── Draft.js
│ │ │ ├── Room.css
│ │ │ ├── Room.js
│ │ │ └── Slider
│ │ │ │ └── Slider.js
│ │ ├── Team Page
│ │ │ └── TeamPage.js
│ │ ├── TextEditor
│ │ │ └── TextEditor.js
│ │ ├── WhiteBoard
│ │ │ ├── Board
│ │ │ │ ├── Board.css
│ │ │ │ └── Board.js
│ │ │ ├── Container
│ │ │ │ ├── Container.css
│ │ │ │ └── Container.js
│ │ │ └── Whiteboard.js
│ │ ├── socket.io.js
│ │ └── trial
│ │ │ └── trial.js
│ ├── Constant
│ │ └── UserConst.js
│ ├── Protected.js
│ ├── Reducer
│ │ ├── UserReducer.js
│ │ └── index.js
│ ├── bootstrap.min.css
│ ├── index.css
│ ├── index.js
│ ├── logo.svg
│ ├── reportWebVitals.js
│ ├── setupTests.js
│ └── store.js
└── tailwind.config.js
├── docker-compose.yml
├── imageTour.md
├── package-lock.json
├── package.json
└── server
├── config
└── db.js
├── controllers
├── pwd.controllers.js
├── room.controllers.js
└── user.controllers.js
├── middleware
├── auth.middleware.js
└── ratelimiter.middleware.js
├── models
├── room.model.js
└── user.modal.js
├── routes
├── pwd.route.js
├── room.route.js
└── user.route.js
├── server.js
└── socket.user.js
/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Code-Deeper/code-sync/34acd71637fee3f324ee75da64786c2f45614622/.DS_Store
--------------------------------------------------------------------------------
/.env.example:
--------------------------------------------------------------------------------
1 | NODE_ENV=development
2 | PORT=8080
3 | MONGO_URI="Write MongoDB URL"
4 | JWT_SECRET_KEY="Write Any JWR Secrets"
5 | FRONTEND_URL="Write Frontend PORT"
6 |
--------------------------------------------------------------------------------
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | # These are supported funding model platforms
2 |
3 | github: codewithvk
4 | patreon: # Replace with a single Patreon username
5 | open_collective: # Replace with a single Open Collective username
6 | ko_fi: # Replace with a single Ko-fi username
7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
9 | liberapay: # Replace with a single Liberapay username
10 | issuehunt: # Replace with a single IssueHunt username
11 | otechie: # Replace with a single Otechie username
12 | custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
13 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/bug_report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Bug report
3 | about: Create a report to help us improve
4 | title: ''
5 | labels: ''
6 | assignees: ''
7 |
8 | ---
9 |
10 | **Describe the bug**
11 | A clear and concise description of what the bug is.
12 |
13 | **To Reproduce**
14 | Steps to reproduce the behavior:
15 | 1. Go to '...'
16 | 2. Click on '....'
17 | 3. Scroll down to '....'
18 | 4. See error
19 |
20 | **Expected behavior**
21 | A clear and concise description of what you expected to happen.
22 |
23 | **Screenshots**
24 | If applicable, add screenshots to help explain your problem.
25 |
26 | **Desktop (please complete the following information):**
27 | - OS: [e.g. iOS]
28 | - Browser [e.g. chrome, safari]
29 | - Version [e.g. 22]
30 |
31 | **Smartphone (please complete the following information):**
32 | - Device: [e.g. iPhone6]
33 | - OS: [e.g. iOS8.1]
34 | - Browser [e.g. stock browser, safari]
35 | - Version [e.g. 22]
36 |
37 | **Additional context**
38 | Add any other context about the problem here.
39 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature_request.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Feature request
3 | about: Suggest an idea for this project
4 | title: ''
5 | labels: ''
6 | assignees: ''
7 |
8 | ---
9 |
10 | **Is your feature request related to a problem? Please describe.**
11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
12 |
13 | **Describe the solution you'd like**
14 | A clear and concise description of what you want to happen.
15 |
16 | **Describe alternatives you've considered**
17 | A clear and concise description of any alternative solutions or features you've considered.
18 |
19 | **Additional context**
20 | Add any other context or screenshots about the feature request here.
21 |
--------------------------------------------------------------------------------
/.github/workflows/greetings.yml:
--------------------------------------------------------------------------------
1 | name: Greetings
2 |
3 | on: [pull_request, issues]
4 |
5 | jobs:
6 | greeting:
7 | runs-on: ubuntu-latest
8 | permissions:
9 | issues: write
10 | pull-requests: write
11 | steps:
12 | - uses: actions/first-interaction@v1
13 | with:
14 | repo-token: ${{ secrets.GITHUB_TOKEN }}
15 | issue-message: 'Message that will be displayed on users first issue'
16 | pr-message: 'Message that will be displayed on users first pull request'
17 |
--------------------------------------------------------------------------------
/.github/workflows/node.js.yml:
--------------------------------------------------------------------------------
1 | # This workflow will do a clean install of node dependencies, build the source code and run tests across different versions of node
2 | # For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions
3 |
4 | name: Node.js CI
5 |
6 | on:
7 | push:
8 | branches: [ main ]
9 | pull_request:
10 | branches: [ main ]
11 |
12 | jobs:
13 | build:
14 |
15 | runs-on: ubuntu-latest
16 |
17 | strategy:
18 | matrix:
19 | node-version: [12.x, 14.x, 16.x]
20 | # See supported Node.js release schedule at https://nodejs.org/en/about/releases/
21 |
22 | steps:
23 | - uses: actions/checkout@v2
24 | - name: Use Node.js ${{ matrix.node-version }}
25 | uses: actions/setup-node@v2
26 | with:
27 | node-version: ${{ matrix.node-version }}
28 | - run: npm ci
29 | - run: npm run build --if-present
30 |
31 |
--------------------------------------------------------------------------------
/.github/workflows/npm-publish.yml:
--------------------------------------------------------------------------------
1 | # This workflow will run tests using node and then publish a package to GitHub Packages when a release is created
2 | # For more information see: https://help.github.com/actions/language-and-framework-guides/publishing-nodejs-packages
3 |
4 | name: Node.js Package
5 |
6 | on:
7 | release:
8 | types: [created]
9 |
10 | jobs:
11 | build:
12 | runs-on: ubuntu-latest
13 | steps:
14 | - uses: actions/checkout@v2
15 | - uses: actions/setup-node@v2
16 | with:
17 | node-version: 12
18 | - run: npm ci
19 | - run: npm test
20 |
21 | publish-npm:
22 | needs: build
23 | runs-on: ubuntu-latest
24 | steps:
25 | - uses: actions/checkout@v2
26 | - uses: actions/setup-node@v2
27 | with:
28 | node-version: 12
29 | registry-url: https://registry.npmjs.org/
30 | - run: npm ci
31 | - run: npm publish
32 | env:
33 | NODE_AUTH_TOKEN: ${{secrets.npm_token}}
34 |
35 | publish-gpr:
36 | needs: build
37 | runs-on: ubuntu-latest
38 | permissions:
39 | contents: read
40 | packages: write
41 | steps:
42 | - uses: actions/checkout@v2
43 | - uses: actions/setup-node@v2
44 | with:
45 | node-version: 12
46 | registry-url: https://npm.pkg.github.com/
47 | - run: npm ci
48 | - run: npm publish
49 | env:
50 | NODE_AUTH_TOKEN: ${{secrets.GITHUB_TOKEN}}
51 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | /node_modules
2 | .env
3 |
--------------------------------------------------------------------------------
/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | # Contributor Covenant Code of Conduct
2 |
3 | ## Our Pledge
4 |
5 | We as members, contributors, and leaders pledge to make participation in our
6 | community a harassment-free experience for everyone, regardless of age, body
7 | size, visible or invisible disability, ethnicity, sex characteristics, gender
8 | identity and expression, level of experience, education, socio-economic status,
9 | nationality, personal appearance, race, religion, or sexual identity
10 | and orientation.
11 |
12 | We pledge to act and interact in ways that contribute to an open, welcoming,
13 | diverse, inclusive, and healthy community.
14 |
15 | ## Our Standards
16 |
17 | Examples of behavior that contributes to a positive environment for our
18 | community include:
19 |
20 | * Demonstrating empathy and kindness toward other people
21 | * Being respectful of differing opinions, viewpoints, and experiences
22 | * Giving and gracefully accepting constructive feedback
23 | * Accepting responsibility and apologizing to those affected by our mistakes,
24 | and learning from the experience
25 | * Focusing on what is best not just for us as individuals, but for the
26 | overall community
27 |
28 | Examples of unacceptable behavior include:
29 |
30 | * The use of sexualized language or imagery, and sexual attention or
31 | advances of any kind
32 | * Trolling, insulting or derogatory comments, and personal or political attacks
33 | * Public or private harassment
34 | * Publishing others' private information, such as a physical or email
35 | address, without their explicit permission
36 | * Other conduct which could reasonably be considered inappropriate in a
37 | professional setting
38 |
39 | ## Enforcement Responsibilities
40 |
41 | Community leaders are responsible for clarifying and enforcing our standards of
42 | acceptable behavior and will take appropriate and fair corrective action in
43 | response to any behavior that they deem inappropriate, threatening, offensive,
44 | or harmful.
45 |
46 | Community leaders have the right and responsibility to remove, edit, or reject
47 | comments, commits, code, wiki edits, issues, and other contributions that are
48 | not aligned to this Code of Conduct, and will communicate reasons for moderation
49 | decisions when appropriate.
50 |
51 | ## Scope
52 |
53 | This Code of Conduct applies within all community spaces, and also applies when
54 | an individual is officially representing the community in public spaces.
55 | Examples of representing our community include using an official e-mail address,
56 | posting via an official social media account, or acting as an appointed
57 | representative at an online or offline event.
58 |
59 | ## Enforcement
60 |
61 | Instances of abusive, harassing, or otherwise unacceptable behavior may be
62 | reported to the community leaders responsible for enforcement at
63 | work.vivekjaviya@gmail.com.
64 | All complaints will be reviewed and investigated promptly and fairly.
65 |
66 | All community leaders are obligated to respect the privacy and security of the
67 | reporter of any incident.
68 |
69 | ## Enforcement Guidelines
70 |
71 | Community leaders will follow these Community Impact Guidelines in determining
72 | the consequences for any action they deem in violation of this Code of Conduct:
73 |
74 | ### 1. Correction
75 |
76 | **Community Impact**: Use of inappropriate language or other behavior deemed
77 | unprofessional or unwelcome in the community.
78 |
79 | **Consequence**: A private, written warning from community leaders, providing
80 | clarity around the nature of the violation and an explanation of why the
81 | behavior was inappropriate. A public apology may be requested.
82 |
83 | ### 2. Warning
84 |
85 | **Community Impact**: A violation through a single incident or series
86 | of actions.
87 |
88 | **Consequence**: A warning with consequences for continued behavior. No
89 | interaction with the people involved, including unsolicited interaction with
90 | those enforcing the Code of Conduct, for a specified period of time. This
91 | includes avoiding interactions in community spaces as well as external channels
92 | like social media. Violating these terms may lead to a temporary or
93 | permanent ban.
94 |
95 | ### 3. Temporary Ban
96 |
97 | **Community Impact**: A serious violation of community standards, including
98 | sustained inappropriate behavior.
99 |
100 | **Consequence**: A temporary ban from any sort of interaction or public
101 | communication with the community for a specified period of time. No public or
102 | private interaction with the people involved, including unsolicited interaction
103 | with those enforcing the Code of Conduct, is allowed during this period.
104 | Violating these terms may lead to a permanent ban.
105 |
106 | ### 4. Permanent Ban
107 |
108 | **Community Impact**: Demonstrating a pattern of violation of community
109 | standards, including sustained inappropriate behavior, harassment of an
110 | individual, or aggression toward or disparagement of classes of individuals.
111 |
112 | **Consequence**: A permanent ban from any sort of public interaction within
113 | the community.
114 |
115 | ## Attribution
116 |
117 | This Code of Conduct is adapted from the [Contributor Covenant][homepage],
118 | version 2.0, available at
119 | https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
120 |
121 | Community Impact Guidelines were inspired by [Mozilla's code of conduct
122 | enforcement ladder](https://github.com/mozilla/diversity).
123 |
124 | [homepage]: https://www.contributor-covenant.org
125 |
126 | For answers to common questions about this code of conduct, see the FAQ at
127 | https://www.contributor-covenant.org/faq. Translations are available at
128 | https://www.contributor-covenant.org/translations.
129 |
--------------------------------------------------------------------------------
/CONTRIBUTE.md:
--------------------------------------------------------------------------------
1 | ### Setup the repository to your local environment.💌
2 | 1. `Fork` the repository - Creates a replica of repository to your local environment.
3 | 2. Clone the repository - Downloads all repo files to your machine, using
4 | ```git
5 | git clone https://github.com/YOUR-USERNAME/code-sync
6 | ```
7 | 3. Set working directory to the root directory of the project.
8 | ```sh
9 | cd code-sync
10 | ```
11 | ## Frontend ⚛️
12 |
13 | Following are the steps to run the frontend of the community-website on your local. All the frontend code will go in the `client` directory.
14 |
15 | 1. Navigate to `client` folder.
16 | ```sh
17 | cd client
18 | ```
19 | 2. Install all the required packages and dependencies.
20 | ```node
21 | npm install
22 | ```
23 | 3. Rename ```.env.example``` to ```.env``` & Fill data as described.
24 |
25 |
26 | ## Backend 💻
27 |
28 | Following are the steps to run the backend of the community-website on your local. All the backend code will go in the `@root` folder.
29 |
30 | 1. Install all the required packages and dependencies on ```@Root``` folder under ```code-sync``` directory.
31 | ```node
32 | npm install
33 | ```
34 | 2. Rename ```.env.example``` to ```.env``` & Fill data as described.
35 |
36 | ## Run/Compile ⏱️
37 | - If you wanna run frontend and backend at one time then you can run command
38 |
39 | ```node
40 | npm run dev
41 | ```
42 | - For Just Frontend/Client
43 |
44 | ```node
45 | npm run client
46 | ```
47 | - For Backend/Server
48 |
49 | ```node
50 | npm run server
51 | ```
52 | - Backend Run on port ```localhost:ENV_PORT``` & Frontend Run on ```localhost:3000```
53 |
--------------------------------------------------------------------------------
/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM node:14.18
2 |
3 | LABEL version="1.0"
4 | LABEL description="This is the base docker image for the codeSync Backend Nodejs & Express Server."
5 | LABEL maintainer = ["codedeeper.work@gmail.com", "work.vivekjaviya@gmail.com"]
6 |
7 | WORKDIR /usr/src/app/backend
8 |
9 | COPY ["package.json", "package-lock.json", "./"]
10 |
11 | RUN npm install --production
12 |
13 | COPY . .
14 |
15 | EXPOSE 8080
16 |
17 | CMD ["npm", "run", "server"]
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2021 Code Deeper
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # CodeSync
2 | ### ⚠️ The site is no longer live, but you can watch the video to learn more 🛑
3 |
4 |
5 | [](#issues)
6 | [](#forks)
7 | [](#license)
8 |
9 | [.png)](https://youtu.be/5IUfY_Pqj_s)
10 |
👨🏾💻 A Cloud Collebrative Platform 🧑🏫
11 |
12 | CodeSync is a Cloud Collaborative Platform for Competitive programmers, Educators & who like to code with friends. CodeSync Provide Collebrative Code-Editor,
13 | Real-Time Audio Communication, Collaborative Drawing board for explain idea, Collaborative text-editor for taking notes, Real-Time chat box for chatting
14 | with other room members & Many more things with smooth and attractive UI.
15 |
16 | ## Tech Stack 🗃
17 | 
18 |
19 |
20 |
21 |
22 | ## How to Setup Project In Local ? 🧑🏽💻
23 | - For Local Installation & Contribute , You can refer [Contribute.md](https://github.com/Code-Deeper/code-sync/blob/main/CONTRIBUTE.md)
24 |
25 | ## Features 📈
26 | - [x] Collebrative Room Create & Join
27 | - [x] Collebrative Code-Editor
28 | - [x] Collebrative White-Board
29 | - [x] Real Time Audio Communcation
30 | - [x] Real Time Chat Messaging
31 | - [x] Collebrative Text-editor
32 | - [x] Compiler Programe
33 | - [x] Invitation On Email
34 | - [x] Template added when change language
35 |
36 | ## Project Management
37 | - For Any Query / Improvement You can mail on ```work.vivekjaviya@gmail.com```.
38 | ## Image Tour
39 | - You can see Image Tour [here](https://github.com/Code-Deeper/code-sync/blob/main/imageTour.md)
40 |
41 | ## License & copyright
42 | - © 2021, Code-Deeper
43 | - Licensed under the [MIT License](LICENSE).
44 |
--------------------------------------------------------------------------------
/assets/CD.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Code-Deeper/code-sync/34acd71637fee3f324ee75da64786c2f45614622/assets/CD.png
--------------------------------------------------------------------------------
/assets/Readme.md:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/assets/audio-room.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Code-Deeper/code-sync/34acd71637fee3f324ee75da64786c2f45614622/assets/audio-room.png
--------------------------------------------------------------------------------
/assets/chat-room.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Code-Deeper/code-sync/34acd71637fee3f324ee75da64786c2f45614622/assets/chat-room.png
--------------------------------------------------------------------------------
/assets/code-editor.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Code-Deeper/code-sync/34acd71637fee3f324ee75da64786c2f45614622/assets/code-editor.png
--------------------------------------------------------------------------------
/assets/codesync.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Code-Deeper/code-sync/34acd71637fee3f324ee75da64786c2f45614622/assets/codesync.png
--------------------------------------------------------------------------------
/assets/compile-code.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Code-Deeper/code-sync/34acd71637fee3f324ee75da64786c2f45614622/assets/compile-code.png
--------------------------------------------------------------------------------
/assets/head.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Code-Deeper/code-sync/34acd71637fee3f324ee75da64786c2f45614622/assets/head.png
--------------------------------------------------------------------------------
/assets/join.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Code-Deeper/code-sync/34acd71637fee3f324ee75da64786c2f45614622/assets/join.png
--------------------------------------------------------------------------------
/assets/main.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Code-Deeper/code-sync/34acd71637fee3f324ee75da64786c2f45614622/assets/main.png
--------------------------------------------------------------------------------
/assets/members.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Code-Deeper/code-sync/34acd71637fee3f324ee75da64786c2f45614622/assets/members.png
--------------------------------------------------------------------------------
/assets/multi-theme.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Code-Deeper/code-sync/34acd71637fee3f324ee75da64786c2f45614622/assets/multi-theme.png
--------------------------------------------------------------------------------
/assets/multi-theme2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Code-Deeper/code-sync/34acd71637fee3f324ee75da64786c2f45614622/assets/multi-theme2.png
--------------------------------------------------------------------------------
/assets/text-editor.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Code-Deeper/code-sync/34acd71637fee3f324ee75da64786c2f45614622/assets/text-editor.png
--------------------------------------------------------------------------------
/assets/user-auth.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Code-Deeper/code-sync/34acd71637fee3f324ee75da64786c2f45614622/assets/user-auth.png
--------------------------------------------------------------------------------
/assets/white-board.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Code-Deeper/code-sync/34acd71637fee3f324ee75da64786c2f45614622/assets/white-board.png
--------------------------------------------------------------------------------
/client/.env.example:
--------------------------------------------------------------------------------
1 | REACT_APP_JAUDGE_LINK_HOST="HOSTURL"
2 | REACT_APP_JAUDGE_API_KEY="Compiler API KEY"
3 | REACT_APP_API_URL="Compiler API URL"
4 | REACT_APP_GOOGLE_CLIENT_API_KEY="Google Console API"
5 | REACT_APP_BASE_URL="Frontend URL"
6 | REACT_APP_BACKEND_URL="Backend URL"
--------------------------------------------------------------------------------
/client/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 |
8 | # testing
9 | /coverage
10 |
11 | # production
12 | /build
13 |
14 | # misc
15 | .DS_Store
16 | .env
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 |
--------------------------------------------------------------------------------
/client/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM node:14.18
2 |
3 | LABEL version="1.0"
4 | LABEL description="This is the base docker image for the codeSync frontend react app."
5 | LABEL maintainer = [ "work.vivekjaviya@gmail.com"]
6 |
7 | WORKDIR /usr/src/app/client
8 |
9 | COPY ["package.json", "package-lock.json", "./"]
10 |
11 | RUN npm install --production
12 |
13 | COPY . .
14 |
15 | EXPOSE 3000
16 |
17 | CMD ["npm", "start"]
--------------------------------------------------------------------------------
/client/README.md:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/client/craco.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | style: {
3 | postcss: {
4 | plugins: [
5 | require('tailwindcss'),
6 | require('autoprefixer'),
7 | ],
8 | },
9 | },
10 | }
--------------------------------------------------------------------------------
/client/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "client",
3 | "version": "0.1.0",
4 | "private": true,
5 | "license": "MIT",
6 | "description": "CodeSync is cloud collaborative tool for student , Teachers and Professional to enjoy coding!",
7 | "keywords": [
8 | "CodeSync",
9 | "Coding tool",
10 | "Cloud tool for coding",
11 | "Real time IDE",
12 | "Real time drawing board"
13 | ],
14 | "author": "Vivekkumar Javiya",
15 | "dependencies": {
16 | "@craco/craco": "^6.3.0",
17 | "@emotion/react": "^11.4.1",
18 | "@emotion/styled": "^11.3.0",
19 | "@fortawesome/fontawesome-free": "^5.15.4",
20 | "@headlessui/react": "^1.4.1",
21 | "@mui/icons-material": "^5.0.1",
22 | "@mui/material": "^5.0.1",
23 | "@testing-library/jest-dom": "^5.14.1",
24 | "@testing-library/react": "^11.2.7",
25 | "@testing-library/user-event": "^12.8.3",
26 | "ace-builds": "^1.4.12",
27 | "axios": "^0.21.4",
28 | "base-64": "^1.0.0",
29 | "cross-env": "^7.0.3",
30 | "dotenv": "^10.0.0",
31 | "draft-js": "^0.11.7",
32 | "history": "^5.0.1",
33 | "jwt-decode": "^3.1.2",
34 | "peerjs": "^1.3.2",
35 | "prop-types": "^15.7.2",
36 | "react": "^17.0.2",
37 | "react-ace": "^9.4.1",
38 | "react-activity": "^2.1.1",
39 | "react-avatar": "^3.10.0",
40 | "react-dom": "^17.0.2",
41 | "react-draft-wysiwyg": "^1.14.7",
42 | "react-ga": "^3.3.0",
43 | "react-google-login": "^5.2.2",
44 | "react-helmet": "^6.1.0",
45 | "react-icons": "^4.3.1",
46 | "react-iframe": "^1.8.0",
47 | "react-loader-advanced": "^1.7.1",
48 | "react-redux": "^7.2.5",
49 | "react-responsive": "^9.0.0-beta.5",
50 | "react-router": "^5.2.0",
51 | "react-router-dom": "^5.2.0",
52 | "react-router-redux": "^4.0.8",
53 | "react-scripts": "4.0.3",
54 | "react-split-pane": "^0.1.92",
55 | "react-toastify": "^8.0.3",
56 | "redux": "^4.1.1",
57 | "redux-devtools-extension": "^2.13.9",
58 | "redux-thunk": "^2.3.0",
59 | "socket.io-client": "^4.1.2",
60 | "universal-cookie": "^4.0.4",
61 | "uuid": "^8.3.2",
62 | "web-vitals": "^1.1.2"
63 | },
64 | "scripts": {
65 | "start": "TAILWIND_MODE=watch craco start",
66 | "build": "craco build",
67 | "test": "craco test"
68 | },
69 | "eslintConfig": {
70 | "extends": [
71 | "react-app",
72 | "react-app/jest"
73 | ]
74 | },
75 | "browserslist": {
76 | "production": [
77 | ">0.2%",
78 | "not dead",
79 | "not op_mini all"
80 | ],
81 | "development": [
82 | "last 1 chrome version",
83 | "last 1 firefox version",
84 | "last 1 safari version"
85 | ]
86 | },
87 | "devDependencies": {
88 | "autoprefixer": "^9.8.8",
89 | "postcss": "^7.0.39",
90 | "tailwindcss": "npm:@tailwindcss/postcss7-compat@^2.2.17"
91 | }
92 | }
93 |
--------------------------------------------------------------------------------
/client/public/android-chrome-192x192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Code-Deeper/code-sync/34acd71637fee3f324ee75da64786c2f45614622/client/public/android-chrome-192x192.png
--------------------------------------------------------------------------------
/client/public/android-chrome-512x512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Code-Deeper/code-sync/34acd71637fee3f324ee75da64786c2f45614622/client/public/android-chrome-512x512.png
--------------------------------------------------------------------------------
/client/public/apple-touch-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Code-Deeper/code-sync/34acd71637fee3f324ee75da64786c2f45614622/client/public/apple-touch-icon.png
--------------------------------------------------------------------------------
/client/public/favicon-16x16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Code-Deeper/code-sync/34acd71637fee3f324ee75da64786c2f45614622/client/public/favicon-16x16.png
--------------------------------------------------------------------------------
/client/public/favicon-32x32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Code-Deeper/code-sync/34acd71637fee3f324ee75da64786c2f45614622/client/public/favicon-32x32.png
--------------------------------------------------------------------------------
/client/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Code-Deeper/code-sync/34acd71637fee3f324ee75da64786c2f45614622/client/public/favicon.ico
--------------------------------------------------------------------------------
/client/public/image/Logos/codesync-01.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Code-Deeper/code-sync/34acd71637fee3f324ee75da64786c2f45614622/client/public/image/Logos/codesync-01.png
--------------------------------------------------------------------------------
/client/public/image/Logos/logo-01.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/client/public/image/Logos/logo-02.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/client/public/image/Logos/pattern-01.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Code-Deeper/code-sync/34acd71637fee3f324ee75da64786c2f45614622/client/public/image/Logos/pattern-01.png
--------------------------------------------------------------------------------
/client/public/image/Logos/sample.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Code-Deeper/code-sync/34acd71637fee3f324ee75da64786c2f45614622/client/public/image/Logos/sample.png
--------------------------------------------------------------------------------
/client/public/image/Logos/xyz.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Code-Deeper/code-sync/34acd71637fee3f324ee75da64786c2f45614622/client/public/image/Logos/xyz.png
--------------------------------------------------------------------------------
/client/public/image/Logos/xyz2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Code-Deeper/code-sync/34acd71637fee3f324ee75da64786c2f45614622/client/public/image/Logos/xyz2.png
--------------------------------------------------------------------------------
/client/public/image/Team/1637646334769.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Code-Deeper/code-sync/34acd71637fee3f324ee75da64786c2f45614622/client/public/image/Team/1637646334769.png
--------------------------------------------------------------------------------
/client/public/image/Team/harsh.JPG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Code-Deeper/code-sync/34acd71637fee3f324ee75da64786c2f45614622/client/public/image/Team/harsh.JPG
--------------------------------------------------------------------------------
/client/public/image/Team/jayraj.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Code-Deeper/code-sync/34acd71637fee3f324ee75da64786c2f45614622/client/public/image/Team/jayraj.jpg
--------------------------------------------------------------------------------
/client/public/image/Team/vivek.JPG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Code-Deeper/code-sync/34acd71637fee3f324ee75da64786c2f45614622/client/public/image/Team/vivek.JPG
--------------------------------------------------------------------------------
/client/public/image/codesynclogo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Code-Deeper/code-sync/34acd71637fee3f324ee75da64786c2f45614622/client/public/image/codesynclogo.png
--------------------------------------------------------------------------------
/client/public/image/email-pattern.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Code-Deeper/code-sync/34acd71637fee3f324ee75da64786c2f45614622/client/public/image/email-pattern.png
--------------------------------------------------------------------------------
/client/public/image/eraser.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Code-Deeper/code-sync/34acd71637fee3f324ee75da64786c2f45614622/client/public/image/eraser.png
--------------------------------------------------------------------------------
/client/public/image/icons/CodeSync-type-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Code-Deeper/code-sync/34acd71637fee3f324ee75da64786c2f45614622/client/public/image/icons/CodeSync-type-logo.png
--------------------------------------------------------------------------------
/client/public/image/icons/chat-22.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
6 |
7 |
8 |
12 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
--------------------------------------------------------------------------------
/client/public/image/icons/chat.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
6 |
7 |
9 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
--------------------------------------------------------------------------------
/client/public/image/icons/close.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/client/public/image/icons/code-room.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/client/public/image/icons/coding.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/client/public/image/icons/compiler.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/client/public/image/icons/copy-svgrepo-com.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
6 |
17 |
20 |
23 |
26 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
--------------------------------------------------------------------------------
/client/public/image/icons/copy.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
8 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/client/public/image/icons/download.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
6 |
7 |
8 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
--------------------------------------------------------------------------------
/client/public/image/icons/drawing-svgrepo.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
6 |
7 |
16 |
17 |
18 |
19 |
20 |
25 |
26 |
27 |
28 |
29 |
31 |
32 |
33 |
34 |
35 |
38 |
39 |
40 |
41 |
42 |
45 |
46 |
47 |
48 |
49 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
--------------------------------------------------------------------------------
/client/public/image/icons/drawing.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
6 |
7 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
--------------------------------------------------------------------------------
/client/public/image/icons/input.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/client/public/image/icons/microphone-voice.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
8 |
9 |
19 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
--------------------------------------------------------------------------------
/client/public/image/icons/mute.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/client/public/image/icons/notes.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
8 |
9 |
10 |
18 |
20 |
22 |
24 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
--------------------------------------------------------------------------------
/client/public/image/icons/pensil.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
8 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
--------------------------------------------------------------------------------
/client/public/image/icons/send.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
6 |
7 |
9 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
--------------------------------------------------------------------------------
/client/public/image/icons/share.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
6 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
--------------------------------------------------------------------------------
/client/public/image/icons/text-editor-repo.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
--------------------------------------------------------------------------------
/client/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
16 |
17 |
18 |
19 |
20 |
21 |
30 | Code Sync
31 |
84 |
85 |
86 |
87 |
88 | Whiteboard Vali coding!!
89 |
90 |
100 |
101 |
102 |
--------------------------------------------------------------------------------
/client/public/link_icon.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/client/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "React App",
3 | "name": "Create React App Sample",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "64x64 32x32 24x24 16x16",
8 | "type": "image/x-icon"
9 | },
10 | {
11 | "src": "favicon-16x16.png",
12 | "type": "image/png",
13 | "sizes": "192x192"
14 | },
15 | {
16 | "src": "favicon-32x32.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 |
--------------------------------------------------------------------------------
/client/public/robots.txt:
--------------------------------------------------------------------------------
1 | # https://www.robotstxt.org/robotstxt.html
2 | User-agent: *
3 | Disallow:
4 |
--------------------------------------------------------------------------------
/client/public/site.webmanifest:
--------------------------------------------------------------------------------
1 | {"name":"","short_name":"","icons":[{"src":"/android-chrome-192x192.png","sizes":"192x192","type":"image/png"},{"src":"/android-chrome-512x512.png","sizes":"512x512","type":"image/png"}],"theme_color":"#ffffff","background_color":"#ffffff","display":"standalone"}
--------------------------------------------------------------------------------
/client/src/API.js:
--------------------------------------------------------------------------------
1 | import axios from 'axios';
2 | import { BaseURL } from './BaseURL'
3 | const AXIOS = axios.create({
4 | baseURL: BaseURL,
5 | withCredentials: true
6 | });
7 |
8 | AXIOS.interceptors.request.use((req) => {
9 | if (localStorage.getItem('authUser')) {
10 | req.headers.Authorization = 'Bearer ' + JSON.parse(localStorage.getItem('authUser')).token;
11 | }
12 | return req;
13 | })
14 |
15 |
16 |
17 | export default AXIOS;
--------------------------------------------------------------------------------
/client/src/Action/UserAction.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import { ADD_USER, REMOVE_USER, ADD_USER_ERROR, REMOVE_USER_ERROR, AUTHORIZATION} from '../Constant/UserConst'
3 | import axios from 'axios'
4 | import { push } from 'react-router-redux'
5 | import AXIOS from '../API'
6 |
7 | export const addUser = (data) =>
8 | async dispatch => {
9 | try {
10 | dispatch({
11 | type: ADD_USER,
12 | payload: data
13 | })
14 | } catch (err) {
15 | dispatch({
16 | type: ADD_USER_ERROR,
17 | payload: err
18 | })
19 | }
20 | }
21 |
22 | export const removeUser = () =>
23 | async dispatch => {
24 | try {
25 | dispatch({
26 | type: REMOVE_USER,
27 | payload: {}
28 | })
29 | } catch (err) {
30 | dispatch({
31 | type: REMOVE_USER_ERROR,
32 | payload: {}
33 | })
34 | }
35 | }
36 |
37 | export const loginUser = (formData, push) =>
38 | async dispatch => {
39 | try {
40 |
41 | // const { data } = await AXIOS.post('/api/user/login', formData);
42 | // console.log(formData)
43 | dispatch({
44 | type: AUTHORIZATION,
45 | payload: formData
46 | })
47 | // history.push('/room')
48 | // console.log(push)
49 | // console.log("hererer")
50 | // push('/room')
51 | } catch (err) {
52 | console.log(err)
53 | push('/')
54 | }
55 | }
56 |
57 | export const registerUser = (data, history) =>
58 | async dispatch => {
59 | try {
60 | dispatch({
61 | type: AUTHORIZATION,
62 | payload: data
63 | })
64 | history.push('/room')
65 | } catch (err) {
66 | console.log(err)
67 | history?.push('/')
68 | }
69 | }
--------------------------------------------------------------------------------
/client/src/App.css:
--------------------------------------------------------------------------------
1 | /* .App {
2 | text-align: center;
3 | }
4 |
5 | .App-logo {
6 | height: 40vmin;
7 | pointer-events: none;
8 | }
9 |
10 | @media (prefers-reduced-motion: no-preference) {
11 | .App-logo {
12 | animation: App-logo-spin infinite 20s linear;
13 | }
14 | }
15 |
16 | .App-header {
17 | background-color: #282c34;
18 | min-height: 100vh;
19 | display: flex;
20 | flex-direction: column;
21 | align-items: center;
22 | justify-content: center;
23 | font-size: calc(10px + 2vmin);
24 | color: white;
25 | }
26 |
27 | .App-link {
28 | color: #61dafb;
29 | }
30 |
31 | @keyframes App-logo-spin {
32 | from {
33 | transform: rotate(0deg);
34 | }
35 | to {
36 | transform: rotate(360deg);
37 | }
38 | } */
39 |
--------------------------------------------------------------------------------
/client/src/App.js:
--------------------------------------------------------------------------------
1 | import React, { useState, useEffect } from 'react';
2 | import { BrowserRouter as Router, Route, Redirect } from 'react-router-dom';
3 | import { createBrowserHistory } from 'history';
4 |
5 | import Room from './Components/Room/Room';
6 | import HomePage from './Components/HomePage/HomePage';
7 | import Editor from './Components/Editor/Editor';
8 | import JoinRoom from './Components/Room/JoinRoom';
9 | import CreateRoom from './Components/Room/CreateRoom';
10 | import FrontPage from './Components/FrontPage/FrontPage';
11 | import LoginPage from './Components/Auth/Login/LoginPage';
12 | import ForgotPassword from './Components/Auth/ForgotPassword/ForgotPassword';
13 | import ResetPassword from './Components/Auth/ResetPassword/ResetPassword';
14 | import Register from './Components/Auth/Register/Register';
15 | import Cookies from 'universal-cookie';
16 | import ProtectedRoute from './Protected';
17 | import Trial from './Components/trial/trial';
18 | import ReactGA from 'react-ga';
19 | import TeamPage from './Components/Team Page/TeamPage';
20 | import NotFound from './Components/NotFound/NotFound';
21 | import { Helmet } from 'react-helmet';
22 | import { useMediaQuery } from 'react-responsive';
23 | import Mobile from './Components/Mobile/Mobile';
24 | const cookies = new Cookies();
25 | const history = createBrowserHistory();
26 |
27 | const isAuthenticated = JSON.parse(localStorage.getItem('authUser'))?.token;
28 | function App() {
29 | // useEffect(() => {
30 | // console.log({ authroot: isAuthenticated });
31 | // }, [isAuthenticated])
32 | useEffect(() => {
33 | ReactGA.initialize('UA-213485416-1');
34 | ReactGA.pageview(window.location.pathname + window.location.search);
35 | }, []);
36 |
37 | const [loginUser, setLoginUser] = useState(null);
38 | const isDesktopOrLaptop = useMediaQuery({
39 | query: '(min-width: 1224px)',
40 | });
41 | const isBigScreen = useMediaQuery({ query: '(min-width: 1200px)' });
42 |
43 | console.log({ isBigScreen });
44 |
45 | return (
46 | <>
47 |
48 | CodeSync
49 |
53 |
54 | {isBigScreen == true ? (
55 |
56 |
57 |
58 |
59 |
60 | }
63 | exact
64 | />
65 |
66 |
67 |
70 | isAuthenticated ? :
71 | }
72 | exact
73 | />
74 |
75 |
78 | isAuthenticated ? (
79 |
80 | ) : (
81 |
82 | )
83 | }
84 | exact
85 | />
86 |
87 | } exact />
88 |
89 |
90 | ) : (
91 |
92 | )}
93 | >
94 | );
95 | }
96 |
97 | export default App;
98 |
--------------------------------------------------------------------------------
/client/src/App.test.js:
--------------------------------------------------------------------------------
1 | import { render, screen } from '@testing-library/react';
2 | import App from './App';
3 |
4 | test('renders learn react link', () => {
5 | render( );
6 | const linkElement = screen.getByText(/learn react/i);
7 | expect(linkElement).toBeInTheDocument();
8 | });
9 |
--------------------------------------------------------------------------------
/client/src/BaseURL.js:
--------------------------------------------------------------------------------
1 | import dotenv from 'dotenv';
2 | dotenv.config();
3 |
4 | export const BaseURL = process.env.REACT_APP_BACKEND_URL
--------------------------------------------------------------------------------
/client/src/Components/Auth/Login/LoginPage.css:
--------------------------------------------------------------------------------
1 | .login-container {
2 | margin-top: 18%;
3 | margin-left: 65%;
4 | text-align: center;
5 | width: 25%;
6 | height: 50% !important;
7 | }
8 | .submit-buttons {
9 | /* margin-left: ; */
10 | width: 100%;
11 | margin-top: 5%;
12 | margin-left: 4%;
13 | }
14 | .google-button {
15 | margin-top: 2%;
16 | }
17 |
18 | .google-btn {
19 | background-color: rgba(99, 102, 241, 1) !important;
20 | color: #fff !important;
21 | width: 100% !important;
22 | margin: 0 auto !important;
23 | padding: 12px 0 !important;
24 | border-radius: 7px !important;
25 | max-width: 84% !important;
26 | }
27 |
28 | .google-btn:hover {
29 | background-color: rgba(67, 56, 202) !important;
30 | }
31 |
--------------------------------------------------------------------------------
/client/src/Components/Auth/Register/Icon.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | const icon = () => (
4 |
5 |
9 |
10 | );
11 |
12 | export default icon;
--------------------------------------------------------------------------------
/client/src/Components/Editor/Editor.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import AceEditor from "react-ace";
3 | import 'ace-builds/src-noconflict/mode-rust';
4 | import 'ace-builds/src-noconflict/mode-kotlin';
5 | import "ace-builds/src-noconflict/ext-language_tools";
6 | import "ace-builds/src-noconflict/mode-java";
7 | import "ace-builds/src-noconflict/mode-c_cpp";
8 | import "ace-builds/src-noconflict/mode-python";
9 | import "ace-builds/src-noconflict/mode-javascript";
10 | import "ace-builds/src-noconflict/theme-github";
11 | import "ace-builds/src-noconflict/theme-solarized_dark";
12 | import "ace-builds/src-noconflict/theme-dracula";
13 | import "ace-builds/src-noconflict/theme-monokai";
14 | import 'ace-builds/src-noconflict/theme-eclipse';
15 | import 'ace-builds/src-noconflict/theme-tomorrow_night';
16 | import 'ace-builds/src-noconflict/theme-tomorrow_night_blue';
17 | import 'ace-builds/src-noconflict/theme-xcode';
18 | import 'ace-builds/src-noconflict/theme-ambiance';
19 | import 'ace-builds/src-noconflict/theme-solarized_light';
20 | function Editor({ language, theme, body, setBody, height, readOnly, width, fontSize }) {
21 | return (
22 | setBody(value)}
26 | value={body}
27 | width={width}
28 | height={height ? height : "78.7vh"}
29 | readOnly={readOnly ? readOnly : false}
30 | fontSize={fontSize ? (isNaN(+fontSize) ? 12 : +fontSize) : 12}
31 | name="UNIQUE_ID_OF_DIV"
32 | showGutter={true}
33 | editorProps={{ $blockScrolling: true }}
34 | setOptions={{
35 | enableBasicAutocompletion: true,
36 | enableLiveAutocompletion: true,
37 | enableSnippets: true,
38 | }}
39 | />
40 | );
41 | }
42 |
43 | export default Editor;
44 |
--------------------------------------------------------------------------------
/client/src/Components/Error/NotFound.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 |
3 | function NotFound() {
4 | return (
5 |
6 | 404 Error!
7 |
8 | )
9 | }
10 |
11 | export default NotFound
12 |
--------------------------------------------------------------------------------
/client/src/Components/FrontPage/FrontPage.js:
--------------------------------------------------------------------------------
1 | import React, { useEffect, useState } from 'react'
2 | import { connect } from 'react-redux'
3 | import { Link } from 'react-router-dom'
4 | import Avatar from 'react-avatar';
5 | import { useHistory } from 'react-router-dom'
6 | import { Transition } from "@headlessui/react";
7 | import LandingPage from './LandingPage';
8 |
9 | const submitHandler = (e) => {
10 | e.preventDefault()
11 | }
12 | function FrontPage(props) {
13 | const history = useHistory(props);
14 | useEffect(() => {
15 |
16 | const isAuthenticated = JSON.parse(localStorage.getItem('authUser'))?.token
17 | if (isAuthenticated) {
18 | history.push("/room");
19 | // window.location.reload();
20 | }
21 | }, [])
22 |
23 | const [isOpen, setIsOpen] = useState(false);
24 |
25 |
26 | return (
27 |
28 |
29 |
30 |
31 |
32 |
33 |
38 |
39 |
63 |
64 | {/* */}
65 |
66 |
setIsOpen(!isOpen)}
68 | type="button"
69 | className="bg-gray-900 inline-flex items-center justify-center p-2 rounded-md text-gray-400 hover:text-white hover:bg-gray-800 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-offset-gray-800 focus:ring-white"
70 | aria-controls="mobile-menu"
71 | aria-expanded="false"
72 | >
73 | Open main menu
74 | {!isOpen ? (
75 |
83 |
89 |
90 | ) : (
91 |
99 |
105 |
106 | )}
107 |
108 |
109 |
121 |
122 |
123 |
124 |
133 | {(ref) => (
134 |
176 | )}
177 |
178 |
179 |
180 |
181 | )
182 | }
183 |
184 |
185 |
186 | const mapStateToProps = state => ({
187 | authUser: state.user
188 | })
189 |
190 | export default connect(mapStateToProps)(FrontPage)
191 |
192 |
193 |
--------------------------------------------------------------------------------
/client/src/Components/FrontPage/Landing.css:
--------------------------------------------------------------------------------
1 | .home-div-con{
2 | display: flex;
3 | justify-content: flex-start;
4 | height: 100%;
5 | align-items: center;
6 |
7 |
8 |
9 | }
10 | .home-child-1{
11 | display: flex;
12 | width: 50%;
13 | justify-content: flex-start;
14 | align-items: center;
15 |
16 | }
17 |
18 | .home-child-2{
19 | display: flex;
20 | width: 50%;
21 | justify-content: flex-start;
22 | align-items: center;
23 |
24 | }
25 | .con-home-l {
26 | padding-left: 15%;
27 | }
28 | .home-child-1 .con-home-l h1{
29 | font-size: 57px;
30 | line-height: 70px;
31 | font-weight: 900;
32 | }
33 | .home-child-1 .con-home-l .home-cont-text{
34 | font-size: 18px;
35 | /* color: gray; */
36 | /* color: rgba(243, 244, 246); */
37 | --tw-text-opacity: 1;
38 | color: rgba(107, 114, 128, var(--tw-text-opacity));
39 | margin: 2% 0;
40 | line-height: 26px;
41 | }
42 | .bt-home-screen{
43 |
44 | }
--------------------------------------------------------------------------------
/client/src/Components/FrontPage/LandingPage.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import Iframe from 'react-iframe'
3 |
4 | import './Landing.css'
5 | function LandingPage() {
6 | return (
7 | <>
8 |
9 |
10 |
11 |
12 |
13 |
Start Writing Your Best Code.
14 |
Crafting Your Code, Dry Run, Talk To Friends, Chat With Friend, Keep a notes of code & Many More!
15 |
16 |
17 |
18 | {/* rgba(243, 244, 246,1) */}
19 | {/*
20 |
21 |
22 |
23 |
Crafting Your Code, Dry Run, Talk To Friends, Chat With Friend, Keep a notes of code & Many More!
24 |
31 |
32 |
33 |
*/}
34 |
35 |
36 |
37 |
38 |
39 |
40 | {/*
41 |
42 |
43 |
44 |
Crafting Your Code, Dry Run, Talk To Friends, Chat With Friend, Keep a notes of code & Many More!
45 |
52 |
53 |
54 |
*/}
55 |
56 |
57 |
58 |
Our Features
59 |
Check out our list of awesome features below.
60 |
61 |
62 |
63 |
64 |
65 |
Code Editors
66 |
Flexible and draggable code editors with multiple themes, Auto Suggest.
67 |
68 |
69 |
70 |
71 |
72 |
73 |
Voice Chat
74 |
Voice chat between the room that help room member to keep them engaged.
75 |
76 |
77 |
78 |
79 |
80 |
White Board
81 |
White Board for visualizing and showcasing your thought to members.
82 |
83 |
84 |
85 |
86 |
87 |
Compiler
88 |
Compiler your code which written on code editor with input.
89 |
90 |
91 |
92 |
93 |
94 |
Note Book
95 |
To keep write-down your thought and share among room member.
96 |
97 |
98 |
99 |
100 |
101 |
Chat App
102 |
Stay Updated with friends by writing piece of message :)
103 |
104 |
105 |
106 |
107 |
108 |
111 |
112 |
113 |
114 |
115 |
116 |
155 |
156 | >
157 | )
158 | }
159 |
160 | export default LandingPage
161 |
--------------------------------------------------------------------------------
/client/src/Components/Header/Header.css:
--------------------------------------------------------------------------------
1 | .component-of-room-page{
2 |
3 | }
--------------------------------------------------------------------------------
/client/src/Components/HomePage/HomePage.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import Header from '../Header/Header'
3 | function HomePage(props) {
4 | return (
5 |
6 |
7 |
8 |
9 | )
10 | }
11 |
12 | export default HomePage
13 |
--------------------------------------------------------------------------------
/client/src/Components/Input/Input.js:
--------------------------------------------------------------------------------
1 | import { Grid, InputAdornment, TextField, IconButton} from '@mui/material'
2 | import React from 'react'
3 | import VisibilityIcon from '@mui/icons-material/Visibility';
4 | import VisibilityOffIcon from '@mui/icons-material/VisibilityOff';
5 |
6 | function Input(props) {
7 | return (
8 |
9 |
16 |
17 | {props.type === "password" ? : }
18 |
19 |
20 | )
21 | }
22 | : null
23 | }
24 | onChange={props.handleChange}
25 | required
26 | fullWidth
27 | label={props.label}
28 | autoFocus={props.autoFocus}
29 | type={props.type} />
30 |
31 | )
32 | }
33 |
34 | export default Input
35 |
--------------------------------------------------------------------------------
/client/src/Components/Mobile/Mobile.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 |
3 | function Mobile() {
4 | return (
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
15 |
18 |
21 |
24 |
27 |
30 |
33 |
36 |
39 |
42 |
44 |
47 |
50 |
53 |
56 |
59 |
61 |
64 |
67 |
70 |
73 |
76 |
79 |
82 |
85 |
88 |
91 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
This Web App is not supported for mobile, Kindly open in Desktop
103 |
105 | Retry
106 |
107 |
108 |
109 |
110 | )
111 | }
112 |
113 | export default Mobile
114 |
--------------------------------------------------------------------------------
/client/src/Components/NotFound/NotFound.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 |
3 | function NotFound() {
4 | return (
5 |
6 | 404 Error@
7 |
8 | )
9 | }
10 |
11 | export default NotFound
12 |
--------------------------------------------------------------------------------
/client/src/Components/Room/CreateRoom.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 |
3 | import { useState } from 'react';
4 | import axios from 'axios'
5 | import { v4 as uuidv4 } from 'uuid';
6 | import { Link, RouteChildrenProps } from 'react-router-dom';
7 | // import { white } from 'colors';
8 | import AXIOS from '../../API';
9 |
10 |
11 | function CreateRoom({ history }) {
12 | const [roomName, setRoomName] = useState('');
13 |
14 | const handleSubmit = async (e) => {
15 |
16 | // uuid.v4()
17 | const uID = await uuidv4();
18 | // console.log(uID);
19 | AXIOS.post('/api/room', {
20 | room_id: uID,
21 | room_title: roomName,
22 | room_body: "", room_language: "", room_input: ""
23 | }).then((res) => {
24 | // console.log(res);
25 | history.push(`/room/${res.data.data.room_id}`)
26 | }).catch((err) => {
27 | alert('Room Not Created!! axaError!!!');
28 | // console.log(err);
29 | })
30 | }
31 |
32 | return (
33 |
34 |
35 |
36 |
37 |
Enter New Room Name
38 | setRoomName(e.target.value)}
42 | className="form-control"
43 | placeholder="Enter room name"
44 | />
45 |
46 | Create your room or Join another
47 |
48 |
49 |
50 |
51 |
52 | Join Room
53 |
54 |
55 |
56 |
57 | )
58 | }
59 |
60 | export default CreateRoom
61 |
--------------------------------------------------------------------------------
/client/src/Components/Room/DropDown/LanguageDP.js:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Code-Deeper/code-sync/34acd71637fee3f324ee75da64786c2f45614622/client/src/Components/Room/DropDown/LanguageDP.js
--------------------------------------------------------------------------------
/client/src/Components/Room/Email/Invite.js:
--------------------------------------------------------------------------------
1 | import React, { useState } from "react";
2 | import Bounce from "react-activity/dist/Bounce";
3 | import "react-activity/dist/Bounce.css";
4 | import Loader from "react-loader-advanced";
5 | export default function Invite({
6 | showModal,
7 | setShowModal,
8 | emailTextPop,
9 | setEmailTextPop,
10 | sendInviteEmail,
11 | setLoader,
12 | loader,
13 | }) {
14 | // backdrop-filter: blur(3px);
15 | return (
16 |
17 | {showModal ? (
18 | <>
19 |
20 |
21 |
22 |
26 |
27 |
28 | }
29 | >
30 |
31 |
Email Invitation
32 | setShowModal(false)}
35 | >
36 |
37 | ×
38 |
39 |
40 |
41 |
42 |
43 |
44 | Please Enter Email
45 |
46 | setEmailTextPop(e.target.value)}
49 | className="my-4 rounded-md pl-2 text-blueGray-500 text-lg leading-relaxed"
50 | placeholder="Enter Invite Email"
51 | >
52 |
53 |
54 |
55 | setShowModal(false)}
59 | >
60 | Close
61 |
62 | {
66 | setLoader(true);
67 | // setInviteLoader(true);
68 | sendInviteEmail();
69 | }}
70 | >
71 | Invite
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 | >
80 | ) : null}
81 |
82 | );
83 | }
84 |
--------------------------------------------------------------------------------
/client/src/Components/Room/JoinRoom.js:
--------------------------------------------------------------------------------
1 | import React, { useState } from 'react';
2 | import { Link } from 'react-router-dom';
3 |
4 | function JoinRoom(props) {
5 | const [roomId , setRoomId] = useState('');
6 | return (
7 |
8 |
9 |
10 |
11 |
Enter Room ID
12 | setRoomId(e.target.value)}
16 | className="form-control"
17 | placeholder="Enter room id"
18 | />
19 |
20 | Ask from room host or Make your own room
21 |
22 |
23 |
24 |
25 | props.history.push(`/room/${roomId}`)}
27 | className="btn btn-primary col-2 text-lg"
28 | >
29 | Join Room
30 |
31 |
32 |
33 |
34 | )
35 | }
36 |
37 | export default JoinRoom
38 |
--------------------------------------------------------------------------------
/client/src/Components/Room/Language/Default.js:
--------------------------------------------------------------------------------
1 | const allLanguageDefaultCode = {
2 | cpp: `
3 | #include
4 | using namespace std;
5 | int main()
6 | {
7 | // Start writing your code from here!
8 | cout<<"Welcome to CodeSync!";
9 | return 0;
10 | }
11 | `,
12 | c: `
13 | #include
14 | int main()
15 | {
16 | // Stat writing code from here
17 | printf("Welcome to CodeSync");
18 |
19 | return 0;
20 | }
21 | `,
22 | java: `
23 | import java.util.*;
24 | class Main
25 | {
26 | public static void main(String[] args)
27 | {
28 | // Start writing code from here :)
29 | System.out.print("Welcome To CodeSync");
30 | }
31 | }
32 | `,
33 | python: `
34 | # Start writing your code from here
35 | print("Welcome to CodeSync")
36 |
37 | `,
38 | javascript: `
39 | // Start writing your code from here
40 | console.log("Welcome to CodeSync")
41 | `
42 | }
43 | export default allLanguageDefaultCode
--------------------------------------------------------------------------------
/client/src/Components/Room/Message/Message.css:
--------------------------------------------------------------------------------
1 |
2 | .chat-hide {
3 | display: block;
4 | z-index: -100;
5 | }
--------------------------------------------------------------------------------
/client/src/Components/Room/Message/Message.js:
--------------------------------------------------------------------------------
1 | import React, { useState } from 'react'
2 | import { Avatar } from "@mui/material";
3 | import './Message.css'
4 | function Message({ openChat, setOpenChat, msgs, setMsg, msg, SendMessage, user, roomTitle }) {
5 | return (
6 | <>
7 |
8 |
9 |
setOpenChat(false)}>
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
{roomTitle}
19 |
20 |
24 |
25 |
26 |
27 | {msgs.map((msg) => {
28 | if (msg.user.toLowerCase() === user?.result?.familyName?.toLowerCase() || msg.user.toLowerCase() === user?.result?.name?.toLowerCase() ) {
29 | return (
30 |
31 |
32 | {msg.text}
33 |
34 |
35 |
36 | )
37 | } else if (msg.user.toLowerCase() === 'Admin') {
38 | return (
39 | {msg.text}
40 |
41 | )
42 | } else {
43 | return (
44 |
45 |
46 |
47 | {msg.text}
48 |
49 |
50 | )
51 | }
52 | })}
53 |
54 |
55 |
65 |
66 |
67 |
68 | >
69 | )
70 | }
71 |
72 | export default Message
73 |
--------------------------------------------------------------------------------
/client/src/Components/Room/RichEditor/Draft.js:
--------------------------------------------------------------------------------
1 | import React, { useEffect, useState } from "react";
2 | import { Editor } from "react-draft-wysiwyg";
3 | import { EditorState } from 'draft-js'
4 | const Draft = ({ editorState, onEditorStateChange}) => {
5 | return (
6 |
7 |
20 |
21 | )
22 | }
23 |
24 | export default Draft
25 |
26 |
--------------------------------------------------------------------------------
/client/src/Components/Room/Room.css:
--------------------------------------------------------------------------------
1 | .m0{margin: 0 !important;}
2 | .room-body{background-color: #E0E0E0;}
3 |
4 |
5 | .form-container{padding: 20px;position: relative;}
6 | .form-container .ide-header{background: #2f3129;color: #fff;border-radius: 10px 10px 0 0;border-bottom: 1px solid #fff;}
7 | .form-container .ide-header h5{display: inline-block;padding: 10px 30px;font-size: 21px ;}
8 | .form-container .ide-header h5 svg{display: inline-block;margin-right: 10px;}
9 | .form-container .ide-header .btn-save-run{float: right;border-radius: 25px;}
10 | .form-container .ide-header .btn-copy{float: right;border-radius: 25px;margin-right: 20px; box-shadow: 0px -1px 25px -8px rgba(0,0,0,0.3);-webkit-box-shadow: 0px -1px 25px -8px rgba(0,0,0,0.3);-moz-box-shadow: 0px -1px 25px -8px rgba(0,0,0,0.3);}
11 | .form-container .ide-header .ide-selectbox{background: #2f3129;border: 1px solid #fff;border-radius: 6px;padding: 5px 28px 5px 12px;font-size: 17px;font-weight: 800;text-transform: capitalize;}
12 | .form-container .ide-header .ide-selectarrow{position: absolute;width: 15px;top: 15px;right: 10px;}
13 | .form-container .ace_editor{border-radius:0 ;}
14 | .form-container .ip-op-editor .ace_editor{height: 25vh !important;width: 100% !important;}
15 | .form-container .ip-op-editor .ip-op-container{width: 99%;margin-top: 1%;}
16 | .form-container .ip-op-editor .ip-op-container:first-child{margin-right: 1%;}
17 | .form-container .ip-op-editor .ip-op-container:last-child{margin-left: 1%;}
18 | .form-container .text-ip-op {margin-top: 10px;}
19 | .form-container .header-ip-op{background: #2f3129;border-bottom: 1px solid #fff;font-size: 21px;border-radius: 10px 10px 0 0;text-align: left;padding: 5px 30px;color: #fff;}
20 | .form-container .header-ip-op h5 svg{display: inline-block;margin-left: 10px;margin-top: -3px;}
21 | /* .form-container .ide-textarea{position: relative;} */
22 | .form-container .ide-textarea .ide-bottom-run{position: absolute;bottom: 15px;right: 15px;z-index: 11;}
23 | .form-container .ide-textarea .ide-bottom-run button{background-color: #828282;border:1px solid #828282 ;font-size: 21px;padding: 0px 15px;border-radius: 6px;}
24 | .form-container .ide-textarea .ide-bottom-run button:hover{background-color: transparent;color: #828282;}
25 | .form-container .ide-textarea .ide-bottom-left{position: absolute;bottom: 15px;left: 15px;z-index: 11;}
26 | .form-container .ide-textarea .ide-bottom-left ul{margin: 0;padding: 0;list-style: none;}
27 | .form-container .ide-textarea .ide-bottom-left ul li{display: inline-block;margin-right: 10px; }
28 | .wt-board{border-radius: 10px;}
29 | .ide-bot-class{
30 | background: #2f3129;color: #fff;border-radius:0 0 10px 10px ;border-bottom: 1px solid #fff;
31 | position: relative;
32 | padding: 30px;
33 | }
34 | .form-container .ip-op-editor .ip-op-container .ace_editor{
35 | border-radius: 0 0 10px 10px;
36 | }
37 |
38 | .room-button-with-avtar{
39 | width: 43.40% !important;
40 | display: block;
41 | float: right;
42 | }
43 | .join-audio-btn{
44 | border: 1px solid #000;
45 | border-radius: 20px;
46 | overflow: hidden;
47 |
48 | }
49 | .join-audio-btn .close-audio-btn{
50 | width: 40px;
51 | height: 40px;
52 | background-color: #e16a71;
53 | color: white;
54 | padding: 11.5px;
55 | border-radius: 20px;
56 | }
57 | .join-audio-btn .mic-handler-btn{
58 | width: 40px;
59 | height: 37px;
60 | padding: 0 10px;
61 | border-radius: 20px;
62 | margin-left: 10px;
63 | margin-top: -1%;
64 | }
65 |
--------------------------------------------------------------------------------
/client/src/Components/Room/Slider/Slider.js:
--------------------------------------------------------------------------------
1 | import React, { Fragment } from 'react'
2 | import { Dialog, Transition } from '@headlessui/react'
3 | import { Avatar } from "@mui/material";
4 | const Slider = ({ sliderOpen, setSliderOpen, activeUserInRoom}) => {
5 | return (
6 |
7 |
8 |
9 |
10 |
19 |
20 |
21 |
22 |
31 |
32 |
41 |
42 |
setSliderOpen(false)}
46 | >
47 | Close panel
48 |
49 |
50 |
51 |
52 |
53 |
54 | 🚀 Users In Room 🤘
55 |
56 |
57 | {activeUserInRoom && activeUserInRoom.map((user) =>
58 |
59 |
60 |
61 |
{user.name}
62 |
63 |
64 |
65 | )}
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 | )
80 | }
81 |
82 | export default Slider
83 |
--------------------------------------------------------------------------------
/client/src/Components/Team Page/TeamPage.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | function TeamPage() {
3 | return (
4 |
5 |
Back
6 |
7 |
8 |
9 | Meet To Our Team
10 |
11 |
12 | The Talented People Behind the Scenes
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
Vivekkumar Javiya
22 |
Software Engineer || Team Lead
23 |
Vivek is Full-Stack Developer & Open Source Contributor. He is the team lead for this project and promotes team collaboration. he mostly works with features like real-time sync of objects and data for the collaborative purpose, audio communication system, and Room management.
24 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
Harsh Pathar
44 |
Front-end Developer
45 |
Harsh is a frontend developer with more than 2 years of experience. He designed most of the components using Html, CSS / TailwindCss, and many other frontend tools. he had experience in Designing as well so, he suggested some design components as well.
46 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
Harsh Nadiyapara
68 |
Designer
69 |
Harsh is a UX/UI designer & Freelancer as well. he made a preview of code sync design in adobe xd. He Created Logos, Background and helped by guiding us in the Design part.
70 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
Jayraj Kanzariya
91 |
Software Engineer & Game Developer
92 |
Jayraj is Software & Game Developer. He is working on Chat Component and fixing instant bugs. He also helped us with some research parts.
93 |
105 |
106 |
107 |
108 |
109 |
110 |
111 | );
112 | }
113 |
114 | export default TeamPage;
115 |
--------------------------------------------------------------------------------
/client/src/Components/TextEditor/TextEditor.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 |
3 | function TextEditor() {
4 | return (
5 |
6 |
7 |
8 | )
9 | }
10 |
11 | export default TextEditor
12 |
--------------------------------------------------------------------------------
/client/src/Components/WhiteBoard/Board/Board.css:
--------------------------------------------------------------------------------
1 |
2 | .board {
3 | width: 100%;
4 | height: 100%;
5 | }
6 |
7 | .sketch {
8 | width: 100%;
9 | height: 95%;
10 | }
--------------------------------------------------------------------------------
/client/src/Components/WhiteBoard/Board/Board.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import socket from '../../socket.io';
3 | import './Board.css';
4 |
5 | class Board extends React.Component {
6 |
7 | timeout;
8 | socket = socket;
9 |
10 | ctx;
11 | isDrawing = false;
12 |
13 | constructor(props) {
14 | super(props);
15 |
16 | this.socket.on("canvas-data", function (data) {
17 |
18 | var root = this;
19 | var interval = setInterval(function () {
20 | if (root.isDrawing) return;
21 | root.isDrawing = true;
22 | clearInterval(interval);
23 | var image = new Image();
24 | var canvas = document.querySelector('#board');
25 | var ctx = canvas.getContext('2d');
26 | image.onload = function () {
27 | ctx.drawImage(image, 0, 0);
28 |
29 | root.isDrawing = false;
30 | };
31 | image.src = data;
32 | }, 200)
33 | })
34 | }
35 |
36 | componentDidMount() {
37 | this.drawOnCanvas();
38 | }
39 |
40 | componentWillReceiveProps(newProps) {
41 | this.ctx.strokeStyle = newProps.color;
42 | this.ctx.lineWidth = newProps.size;
43 | }
44 |
45 | drawOnCanvas() {
46 | var canvas = document.querySelector('#board');
47 | this.ctx = canvas.getContext('2d');
48 | var ctx = this.ctx;
49 |
50 | var sketch = document.querySelector('#sketch');
51 | var sketch_style = getComputedStyle(sketch);
52 | canvas.width = parseInt(sketch_style.getPropertyValue('width'));
53 | canvas.height = parseInt(sketch_style.getPropertyValue('height'));
54 |
55 | var mouse = { x: 0, y: 0 };
56 | var last_mouse = { x: 0, y: 0 };
57 |
58 | /* Mouse Capturing Work */
59 | canvas.addEventListener('mousemove', function (e) {
60 | last_mouse.x = mouse.x;
61 | last_mouse.y = mouse.y;
62 |
63 | mouse.x = e.pageX - this.offsetLeft;
64 | mouse.y = e.pageY - this.offsetTop;
65 | }, false);
66 |
67 |
68 | /* Drawing on Paint App */
69 | ctx.lineWidth = this.props.size;
70 | ctx.lineJoin = 'round';
71 | ctx.lineCap = 'round';
72 | ctx.strokeStyle = this.props.color;
73 |
74 | canvas.addEventListener('mousedown', function (e) {
75 | canvas.addEventListener('mousemove', onPaint, false);
76 | }, false);
77 |
78 | canvas.addEventListener('mouseup', function () {
79 | canvas.removeEventListener('mousemove', onPaint, false);
80 | }, false);
81 |
82 | var root = this;
83 | var onPaint = function () {
84 | ctx.beginPath();
85 | ctx.moveTo(last_mouse.x, last_mouse.y);
86 | ctx.lineTo(mouse.x, mouse.y);
87 | ctx.closePath();
88 | ctx.stroke();
89 |
90 | if (root.timeout != undefined) clearTimeout(root.timeout);
91 | root.timeout = setTimeout(function () {
92 | var base64ImageData = canvas.toDataURL("image/png");
93 | root.socket.emit("canvas-data", base64ImageData);
94 | }, 1000)
95 | };
96 | }
97 |
98 | render() {
99 | return (
100 |
101 |
102 |
103 | )
104 | }
105 | }
106 |
107 | export default Board
--------------------------------------------------------------------------------
/client/src/Components/WhiteBoard/Container/Container.css:
--------------------------------------------------------------------------------
1 | .container {/* position: ; */margin-top: 20px;width: 85%;height: 100%;border-radius: 10px;}
2 |
3 | .tools-section {display: inline-block;padding: 10px 30px 0 30px;background-color: #fff;margin-left: 7px; margin-top: 10px;border-radius: 10px;width: 32%;float: left;}
4 | .tools-section .color-picker-container{display: inline-block;position: relative;}
5 | .tools-section .color-picker-container label{display: none;}
6 | .tools-section .color-picker-container input{width: 50px;height: 50px;border-radius: 50%;overflow: hidden;}
7 | .tools-section .color-picker-container svg{position: absolute;top: 12px;left: 12px;}
8 | .tools-section .brushsize-container{display: inline-block; border: 1px solid #000;padding: 10px 10px 10px 20px;border-radius: 10px;margin-left: 20px;position: relative;top: -18px;}
9 | .tools-section .brushsize-container label{display: none;}
10 | .tools-section .brushsize-container .pen-color-container{width: 15px;display: block;float: left;margin: 0 10px 0 0;}
11 | .tools-section .brushsize-container .pen-color-container svg{width: 100%;}
12 | .tools-section .brushsize-container .eraser-color-container{width: 20px;display: block;float: left;margin: 0 10px 0 0;}
13 | .tools-section .brushsize-container .eraser-color-container svg{width: 100%;}
14 |
15 | .showcase-section{display: inline-block;padding: 12px ;background-color: #fff;margin-left: 7px; margin-top: 10px;border-radius: 10px;width: 65%;float: left;}
16 | .showcase-section h3{border: 1px solid #000;padding: 13px;border-radius: 10px;text-align: center;}
17 | .showcase-section h3 svg{display: inline-block;float: right;width: 30px;margin-top: -10px;}
18 |
19 | .board-container {width: 98%;height: 80vh;margin: auto;background: white;border-radius: 10px;}
20 | .board-container .board-title{position: relative;top: 0;left: 42%;padding: 5px 15px;border:1px solid #eee;border-top: none;border-radius: 0 0 10px 10px;width: 150px;text-align: center;}
21 | .board-container .board-title h5{width: 100px;}
22 |
23 | .board-container .text-editor-btn-area{position: relative;top: -70%;left: 94%;background-color: #EDEDED;padding: 10px;display: inline-block;border-radius: 10px 0 0 10px;}
24 | .board-container .text-editor-btn-area svg{width: 30px;}
25 |
26 | .text-editor-btn-area .texteditor-section{position: absolute;width: 00px;min-height: 375px; transition:all 0.5s linear;right:0;left:auto;z-index: -111;overflow: hidden;}
27 | .text-editor-btn-area.active .texteditor-section{display: block;width: 800px;z-index: 111;}
28 | .texteditor-section .rdw-editor-main{background-color: #fff;border: 1px solid #f1f1f1 !important; min-height: 250px;}
29 |
30 | .chat-hide {
31 | display: block;
32 | z-index: -100;
33 | }
34 |
35 |
36 |
37 |
38 |
39 | .chat-services{
40 | transition: .5s;
41 | max-height: 0;
42 | }
43 | .chat-services.expand{
44 | max-height: 350px;
45 | }
46 | .message {
47 | max-width: 250px;
48 | }
49 |
50 | .chat-modal{
51 | transition: .5s;
52 | opacity: 0;
53 | transform: translateX(500px);
54 | }
55 |
56 | .chat-modal.show{
57 | opacity: 1;
58 | transform: translateX(0);
59 | }
60 |
61 | @keyframes animateModal {
62 | from{
63 | transform: translateX(200px) opacity(0);
64 | }
65 | to{
66 | transform: translateX(0) opacity(1);
67 | }
68 | }
69 |
70 | @media (max-width:1536px){
71 | /*1536 x 750*/
72 | .tools-section{padding: 10px 20px 0 20px;}
73 | }
74 |
75 |
76 | @media (max-width:1366px) {
77 | /*1366 x 655*/
78 |
79 | .tools-section{padding: 10px 10px 0 15px;}
80 | .tools-section .brushsize-container{margin-left: 5px;}
81 | }
--------------------------------------------------------------------------------
/client/src/Components/WhiteBoard/Container/Container.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import Board from '../Board/Board';
3 | import Draft from '../../Room/RichEditor/Draft'
4 | // import { Avatar } from "@mui/material";
5 | import './Container.css';
6 | class Container extends React.Component {
7 | constructor(props) {
8 | super(props);
9 | this.state = { addClass: false }
10 | this.handleClick = this.handleClick.bind(this)
11 | }
12 | toggle() {
13 | this.setState({ addClass: !this.state.addClass });
14 | }
15 |
16 | changeColor(params) {
17 | this.setState({
18 | color: params.target.value
19 | })
20 | }
21 |
22 | changeSize(params) {
23 | this.setState({
24 | size: params.target.value
25 | })
26 | }
27 | eraseHandler(params) {
28 | this.setState({
29 | color: "#ffffff"
30 | })
31 | }
32 | blackPan(params) {
33 | this.setState({
34 | color: "#000"
35 | })
36 | }
37 | handleClick() {
38 | this.props.setOpenChat(false)
39 | }
40 | render() {
41 | let boxClass = ["text-editor-btn-area"];
42 | if (this.state.addClass) {
43 | boxClass.push('active');
44 | }
45 | // console.log(this.state)
46 | return (
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 | White Board
55 |
56 |
57 |
58 | {this.state.addClass ?
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 | :
68 |
69 |
70 |
71 |
72 |
73 |
74 | }
75 |
76 |
77 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 | Color :
91 |
92 |
93 |
94 |
95 |
Size :
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
109 | 5
110 | 10
111 | 15
112 | 20
113 | 25
114 | 30
115 |
116 |
117 |
118 |
119 |
120 | {this.props.activeUserInRoom} People Join Chatroom
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 | )
129 | }
130 | }
131 |
132 | export default Container
--------------------------------------------------------------------------------
/client/src/Components/WhiteBoard/Whiteboard.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import Container from './Container/Container'
3 |
4 | function Whiteboard(props) {
5 | return (
6 |
7 | < Container
8 | editorState={props.editorState}
9 | setEditorState={props.setEditorState}
10 | onEditorStateChange={props.onEditorStateChange}
11 | setOpenChat={props.setOpenChat}
12 | activeUserInRoom={props.activeUserInRoom}
13 | />
14 |
15 | )
16 | }
17 |
18 | export default Whiteboard
19 |
--------------------------------------------------------------------------------
/client/src/Components/socket.io.js:
--------------------------------------------------------------------------------
1 | import io from 'socket.io-client';
2 | import dotenv from 'dotenv';
3 | dotenv.config();
4 | const socket = io(process.env.REACT_APP_BACKEND_URL);
5 |
6 | export default socket;
--------------------------------------------------------------------------------
/client/src/Components/trial/trial.js:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Code-Deeper/code-sync/34acd71637fee3f324ee75da64786c2f45614622/client/src/Components/trial/trial.js
--------------------------------------------------------------------------------
/client/src/Constant/UserConst.js:
--------------------------------------------------------------------------------
1 | export const ADD_USER = "ADD_USER";
2 | export const ADD_USER_ERROR = "ADD_USER_ERROR";
3 |
4 | export const REMOVE_USER = "REMOVE_USER";
5 | export const REMOVE_USER_ERROR = "REMOVE_USER_ERROR";
6 |
7 | export const AUTHORIZATION = "AUTHORIZATION";
--------------------------------------------------------------------------------
/client/src/Protected.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import { Redirect, Route } from "react-router-dom";
3 |
4 | function ProtectedRoute({ component: Component, ...restOfProps }) {
5 | const isAuthenticated = localStorage.getItem("authUser");
6 |
7 | return (
8 |
11 | isAuthenticated ? :
12 | }
13 | />
14 | );
15 | }
16 |
17 | export default ProtectedRoute;
--------------------------------------------------------------------------------
/client/src/Reducer/UserReducer.js:
--------------------------------------------------------------------------------
1 |
2 | import { ADD_USER, REMOVE_USER, ADD_USER_ERROR, REMOVE_USER_ERROR, AUTHORIZATION} from '../Constant/UserConst'
3 | const initialState = {
4 | loading: true,
5 | data: []
6 | }
7 |
8 | export default function (state = initialState, action) {
9 | // const history = useHistory()
10 | switch (action.type) {
11 | case ADD_USER:
12 | localStorage.setItem('authUser', JSON.stringify({...action?.payload}))
13 | return {
14 | ...state,
15 | loading: false,
16 | data: action.payload
17 | }
18 | case ADD_USER_ERROR:
19 | return {
20 | ...state,
21 | loading: false,
22 |
23 | }
24 | case REMOVE_USER:
25 | localStorage.clear()
26 | return {
27 | ...state,
28 | loading: false,
29 | data: null
30 | }
31 | case REMOVE_USER_ERROR:
32 | return {
33 | ...state,
34 | loading: false,
35 | }
36 | case AUTHORIZATION:
37 | localStorage.setItem('authUser', JSON.stringify({ ...action?.payload }))
38 | return {
39 | ...state,
40 | loading: false,
41 | data: action.payload
42 | }
43 | default:
44 | return state;
45 | }
46 | }
--------------------------------------------------------------------------------
/client/src/Reducer/index.js:
--------------------------------------------------------------------------------
1 | import { combineReducers } from 'redux'
2 | import UserReducer from './UserReducer'
3 |
4 | export default combineReducers({
5 | user: UserReducer,
6 |
7 | })
--------------------------------------------------------------------------------
/client/src/index.css:
--------------------------------------------------------------------------------
1 | @tailwind base;
2 | @tailwind components;
3 | @tailwind utilities;
4 |
5 | body {
6 | margin: 0;
7 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
8 | 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
9 | sans-serif;
10 | -webkit-font-smoothing: antialiased;
11 | -moz-osx-font-smoothing: grayscale;
12 | }
13 |
14 | code {
15 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
16 | monospace;
17 | }
18 |
--------------------------------------------------------------------------------
/client/src/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 | import App from './App';
4 | // import reportWebVitals from './reportWebVitals';
5 | import { Provider } from 'react-redux'
6 | import store from './store'
7 | // import axios from 'axios'
8 |
9 | import './index.css'
10 | // import './bootstrap.min.css';
11 | // axios.interceptors.request.use((req) => {
12 | // if (localStorage.getItem('authUser')) {
13 | // req.headers.Authorization = 'Bearer ' + JSON.parse(localStorage.getItem('authUser')).token;
14 | // }
15 | // return req;
16 | // })
17 |
18 | ReactDOM.render(
19 |
20 |
21 |
22 |
23 |
24 | ,
25 | document.getElementById('root')
26 | );
27 |
28 |
--------------------------------------------------------------------------------
/client/src/logo.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/client/src/reportWebVitals.js:
--------------------------------------------------------------------------------
1 | const reportWebVitals = onPerfEntry => {
2 | if (onPerfEntry && onPerfEntry instanceof Function) {
3 | import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
4 | getCLS(onPerfEntry);
5 | getFID(onPerfEntry);
6 | getFCP(onPerfEntry);
7 | getLCP(onPerfEntry);
8 | getTTFB(onPerfEntry);
9 | });
10 | }
11 | };
12 |
13 | export default reportWebVitals;
14 |
--------------------------------------------------------------------------------
/client/src/setupTests.js:
--------------------------------------------------------------------------------
1 | // jest-dom adds custom jest matchers for asserting on DOM nodes.
2 | // allows you to do things like:
3 | // expect(element).toHaveTextContent(/react/i)
4 | // learn more: https://github.com/testing-library/jest-dom
5 | import '@testing-library/jest-dom';
6 |
--------------------------------------------------------------------------------
/client/src/store.js:
--------------------------------------------------------------------------------
1 | import { createStore, applyMiddleware } from 'redux'
2 | import { composeWithDevTools } from 'redux-devtools-extension'
3 | import thunk from 'redux-thunk'
4 | import rootReducer from './Reducer/index'
5 |
6 |
7 | const initialState = {}
8 |
9 | const middleware = [thunk];
10 | const store = createStore(rootReducer, initialState, composeWithDevTools(applyMiddleware(...middleware)));
11 |
12 |
13 | export default store
--------------------------------------------------------------------------------
/client/tailwind.config.js:
--------------------------------------------------------------------------------
1 | const colors = require('tailwindcss/colors')
2 |
3 | module.exports = {
4 | mode: 'jit',
5 | purge: ['./src/Components/**/*.{js,jsx,ts,tsx}', './public/index.html', './src/components/*.{js,jsx}', './src/Components/**/**/*.{js,jsx,ts,tsx}'],
6 | theme: {
7 | colors: {
8 | gray: colors.coolGray,
9 | blue: colors.blue,
10 | red: colors.rose,
11 | pink: colors.fuchsia,
12 | indigo: colors.indigo,
13 | green: colors.emerald,
14 | // white: colors.white,
15 | yellow : colors.yellow
16 |
17 | },
18 | fontFamily: {
19 | sans: ['Graphik', 'sans-serif'],
20 | serif: ['Merriweather', 'serif'],
21 | },
22 |
23 | },
24 | variants: {
25 | extend: {
26 | // borderColor: ['focus-visible'],
27 | opacity: ['disabled'],
28 | }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/docker-compose.yml:
--------------------------------------------------------------------------------
1 | version: '3'
2 |
3 | services:
4 | backend:
5 | env_file:
6 | ".env"
7 | build:
8 | context: ./
9 | dockerfile: ./Dockerfile
10 | image: "codesync-backend-trial"
11 | ports:
12 | - "8080:8080"
13 | frontend:
14 | env_file:
15 | "./client/.env"
16 | build:
17 | context: ./client
18 | dockerfile: ./Dockerfile
19 | image: "codesync-frontend-trial"
20 | ports:
21 | - "3000:3000"
22 | links:
23 | - "backend:be"
24 |
--------------------------------------------------------------------------------
/imageTour.md:
--------------------------------------------------------------------------------
1 | # Image Tour of entire Application☣️
2 |
3 |
4 |
1. Home-Page
5 |
6 | 2. User Authentication 🔗
7 |
8 | 3. Join room with ID or Create room and share the link to your peers🂠
9 |
10 | 4. Choose your language to code ☞
11 |
12 | 5. Starting cool coding in the Collaborative Code-editor 📝
13 |
14 | 6. Choose your favorite Theme ✨
15 |
16 | 7. Work with Collaborative Text-Editor💶
17 |
18 | 8. See the online members 👩🏻💻
19 |
20 | 9. Starting using chat room 𓀃
21 |
22 | 10. Use Collaborative White-Board for Visualization🔖
23 |
24 |
25 |
26 | Hope you enjoyed, Thanks for Watching!🌻
27 |
28 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "code-sync",
3 | "version": "1.0.0",
4 | "description": "CodeSync is cloud collaborative tool for student , Teachers and Professional to enjoy coding!",
5 | "main": "server.js",
6 | "scripts": {
7 | "start": "node server/server",
8 | "server": "nodemon server/server",
9 | "client": "npm start --prefix client",
10 | "dev": "concurrently \"npm run server\" \"npm run client\"",
11 | "deployment-script": "NPM_CONFIG_PRODUCTION=false npm install --prefix client && npm run build --prefix"
12 | },
13 | "repository": {
14 | "type": "git",
15 | "url": "git+https://github.com/DE-PROJECT/code-sync.git"
16 | },
17 | "keywords": [
18 | "CodeSync",
19 | "Coding tool",
20 | "Cloud tool for coding"
21 | ],
22 | "author": "Vivekkumar Javiya",
23 | "license": "MIT",
24 | "bugs": {
25 | "url": "https://github.com/DE-PROJECT/code-sync/issues"
26 | },
27 | "homepage": "https://github.com/DE-PROJECT/code-sync#readme",
28 | "dependencies": {
29 | "axios": "^0.26.0",
30 | "bcryptjs": "^2.4.3",
31 | "body-parser": "^1.19.0",
32 | "colors": "^1.4.0",
33 | "concurrently": "^6.2.0",
34 | "cors": "^2.8.5",
35 | "cross-env": "^7.0.3",
36 | "dotenv": "^10.0.0",
37 | "express": "^4.17.1",
38 | "express-async-handler": "^1.1.4",
39 | "express-rate-limit": "^5.5.1",
40 | "heroicons": "^1.0.5",
41 | "jsonwebtoken": "^8.5.1",
42 | "mongoose": "^5.12.14",
43 | "morgan": "^1.10.0",
44 | "nodemailer": "^6.7.2",
45 | "nodemon": "^2.0.7",
46 | "randomstring": "^1.2.1",
47 | "socket.io": "^4.1.2"
48 | },
49 | "cspell": {
50 | "version": "0.2",
51 | "ignorePaths": [],
52 | "dictionaryDefinitions": [],
53 | "dictionaries": [],
54 | "words": [],
55 | "ignoreWords": [],
56 | "import": []
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/server/config/db.js:
--------------------------------------------------------------------------------
1 | const mongoose =require('mongoose')
2 | const connectDB = async () => {
3 | try {
4 | const conn = await mongoose.connect(process.env.MONGO_URI, {
5 | useUnifiedTopology: true,
6 | useNewUrlParser: true,
7 | useCreateIndex: true,
8 | })
9 |
10 | console.log(`MongoDB Connected: ${conn.connection.host}`.cyan.underline)
11 | } catch (error) {
12 | console.error(`Error: ${error.message}`.red.underline.bold)
13 | process.exit(1)
14 | }
15 | }
16 |
17 | module.exports = connectDB
--------------------------------------------------------------------------------
/server/controllers/pwd.controllers.js:
--------------------------------------------------------------------------------
1 | const asyncHandler = require('express-async-handler');
2 | const User = require('../models/user.modal');
3 | const nodemailer = require('nodemailer');
4 | const jwt = require('jsonwebtoken');
5 | const bcrypt = require('bcryptjs');
6 |
7 | module.exports.forgotPwdController = asyncHandler(async (req, res, next) => {
8 | const { email } = req.body;
9 | const user = await User.findOne({ email });
10 |
11 | if (!user) {
12 | res.status(400).send({ status: 'user not found' });
13 | throw new Error('User not found');
14 | }
15 |
16 | const token = await user.createPWDresetToken();
17 | const resetURL = `${process.env.FRONTEND_URL}/_reset_password/${token}`;
18 |
19 | var transporter = nodemailer.createTransport({
20 | service: 'gmail',
21 | auth: {
22 | user: process.env.OUR_EMAIL,
23 | pass: process.env.EMAIL_PASS,
24 | },
25 | from: 'codesync.live',
26 | });
27 |
28 | var mailOptions = {
29 | from: process.env.OUR_EMAIL,
30 | to: user.email,
31 | cc: 'codedeeper.work@gmail.com',
32 | subject: 'Codedeeper password reset Token',
33 | html: `Hello , ${user.name} here is your token link. Click Here to reset the password
`,
34 | text: `Hello , ${user.name} here is your token link. Click Here to reset the password
`,
35 | };
36 |
37 | transporter.sendMail(mailOptions, function (error, info) {
38 | if (error) {
39 | console.log(error);
40 | res.status(200).send({
41 | status: 'failed',
42 | });
43 | } else {
44 | console.log('Email sent: ' + info.response);
45 | if (process.env.NODE_ENV == 'development') {
46 | res.status(200).send({
47 | status: 'success',
48 | resetURL,
49 | });
50 | } else {
51 | res.status(200).send({ status: 'mail sent successfully' });
52 | }
53 | }
54 | });
55 | });
56 |
57 | module.exports.resetPasswordController = asyncHandler(async (req, res) => {
58 | const reset_token = req.params.JWT_TOKEN;
59 | try {
60 | const payload = jwt.verify(reset_token, process.env.JWT_SECRET_KEY);
61 | const { password, confirmpassword } = req.body;
62 | if (!password || !confirmpassword)
63 | throw new Error('Password should be provided!');
64 |
65 | if (password !== confirmpassword) throw new Error("Password doesn't match");
66 |
67 | const user = await User.findById(payload.id);
68 | if (!user) throw new Error('No user exists with this id');
69 |
70 | if (user.passwordChangedAt && user.passwordChangedAt > payload.iat * 1000)
71 | throw new Error(
72 | 'Please raise a new Reset Request,this token was used earlier'
73 | );
74 |
75 | const newPassword = await bcrypt.hash(password, 12);
76 | user.set({ password: newPassword, passwordChangedAt: new Date() });
77 | await user.save();
78 |
79 | return res.status(200).send({
80 | status: 'password changed successfully',
81 | });
82 | } catch (err) {
83 | res.status(400).send({
84 | err: err.message,
85 | });
86 | }
87 | });
88 |
--------------------------------------------------------------------------------
/server/controllers/room.controllers.js:
--------------------------------------------------------------------------------
1 | const asyncHandler = require("express-async-handler");
2 | const Room = require("../models/room.model");
3 |
4 | const getRoomByID = asyncHandler(async (req, res) => {
5 |
6 | if (!req.userId) {
7 | return res.status(401).json({ status: 404, message: "UnAuthorized user!!" })
8 | }
9 | const roomIID = req.params.id;
10 | const room = await Room.findOne({ room_id: roomIID });
11 | if (room) {
12 | res.status(200).json(room);
13 | } else {
14 | res.status(400);
15 | throw new Error("Room Not Found!!");
16 | }
17 | });
18 |
19 | const createRoomById = asyncHandler(async (req, res) => {
20 |
21 |
22 | if (!req.userId) {
23 | return res.status(401).json({ status: 404, message: "UnAuthorized user!!" })
24 | }
25 |
26 | const { room_id, room_title, room_body, room_language, room_input } = req.body;
27 | // Edge Case room_id room_title null
28 |
29 | // if (room_id == null || room_title == null) {
30 | // res.status(400);
31 | // throw new Error("Please Enter room id and name!");
32 | // return;
33 | // }
34 |
35 | const newRoom = new Room({
36 | room_id,
37 | room_title,
38 | room_body,
39 | room_language,
40 | room_input,
41 | });
42 | newRoom.save().then((createRoom) => {
43 | res.status(200).json(createRoom);
44 | }).catch((err) => {
45 | res.status(500).json(err);
46 | })
47 |
48 | });
49 |
50 | const updateRoomById = asyncHandler(async (req, res) => {
51 | if (!req.userId) {
52 | return res.status(401).json({ status: 404, message: "UnAuthorized user!!" })
53 | }
54 | const newRoomData = req.body;
55 | const rm_id = req.params.id;
56 | // console.log({newRoomData})
57 | const updateRoomData = await Room.findOneAndUpdate(
58 | { room_id: rm_id },
59 | newRoomData
60 | );
61 | const returnData = await Room.findOne({ room_id: rm_id });
62 | if (!returnData) {
63 | res.status(400).send("Not Update User!");
64 | return;
65 | }
66 | res.status(200).json(returnData);
67 | });
68 | module.exports = { createRoomById, getRoomByID, updateRoomById };
69 |
--------------------------------------------------------------------------------
/server/controllers/user.controllers.js:
--------------------------------------------------------------------------------
1 | const bcrypt = require('bcryptjs')
2 | const jwt = require('jsonwebtoken')
3 | const User = require('./../models/user.modal')
4 | var randomstring = require("randomstring");
5 |
6 |
7 |
8 | const LoginUser = async (req, res) => {
9 | const { email, password } = req.body
10 | try {
11 | const existingUser = await User.findOne({ email: email })
12 | if (!existingUser) {
13 | return res.status(201).json({ code: 201, message: 'User Not Registered' })
14 | }
15 | const isPasswordCorrect = await bcrypt.compare(password, existingUser.password)
16 | if (!isPasswordCorrect) {
17 | return res.status(202).json({ code: 202, message: 'Invalid Password!!' })
18 | }
19 | const token = jwt.sign({ email: existingUser.email, id: existingUser._id }, process.env.JWT_SECRET_KEY, { expiresIn: "1h" })
20 | res.status(200).json({ result: existingUser, token })
21 | } catch (err) {
22 | return res.status(500).json({ code: 500, message: 'Something went to wrong!!' })
23 | }
24 | }
25 | const registerUser = async (req, res) => {
26 | // Sign up
27 | const { email, password, confirmpassword, firstname, lastname } = req.body
28 |
29 | try {
30 | const existingUser = await User.findOne({ email: email })
31 | if (existingUser) {
32 | return res.status(201).json({ code: 201, message: 'User Already Registered!!' })
33 | }
34 | if (password != confirmpassword) {
35 | return res.status(202).json({ code: 202, message: 'Password & Confirm Password are not matched!!' })
36 | }
37 | const hashPassword = await bcrypt.hash(password, 12);
38 | const result = await User.create({ email, password: hashPassword, name: `${firstname} ${lastname}` })
39 | const token = await jwt.sign({ email: result.email, id: result._id }, process.env.JWT_SECRET_KEY, { expiresIn: "24h" })
40 | // console.log({ result, token })
41 | res.status(200).json({ result, token })
42 | } catch (error) {
43 | return res.status(500).json({ code: 500, message: 'Something went to wrong!!' })
44 | }
45 | }
46 |
47 | const googleAuthUser = async (req, res) => {
48 | // Sign up
49 | const { userName, googleLogin, email, imageUrl } = req.body
50 |
51 | try {
52 | const existingUser = await User.findOne({ email: email })
53 | // console.log({ existingUser })
54 | if (existingUser) {
55 | // Login Property
56 |
57 |
58 | const token = jwt.sign({ email: existingUser.email, id: existingUser._id }, process.env.JWT_SECRET_KEY, { expiresIn: "24h" })
59 | return res.status(200).json({ result: existingUser, token })
60 |
61 | } else {
62 | // Registration Property
63 | let password = randomstring.generate(8);
64 | const hashPassword = await bcrypt.hash(password, 12);
65 | const result = await User.create({ email, password: hashPassword, name: userName, imageUrl: imageUrl })
66 | const token = await jwt.sign({ email: result.email, id: result._id }, process.env.JWT_SECRET_KEY, { expiresIn: "24h" })
67 | return res.status(200).json({ result, token })
68 |
69 | }
70 |
71 |
72 |
73 |
74 | return res.status(204).send({});
75 | // console.log({ result, token })
76 |
77 | } catch (error) {
78 | console.log(error)
79 | return res.status(500).json({ code: 500, message: 'Something went to wrong!!' })
80 | }
81 | }
82 | module.exports = { LoginUser, registerUser, googleAuthUser }
--------------------------------------------------------------------------------
/server/middleware/auth.middleware.js:
--------------------------------------------------------------------------------
1 | const jwt = require('jsonwebtoken')
2 | const dotenv = require('dotenv')
3 | dotenv.config()
4 | const authMiddleware = async (req, res, next) => {
5 |
6 | try {
7 | const token = req.headers.authorization?.split(' ')?.[1]
8 | if (!token) {
9 | res.status(401)
10 | throw new Error('Not authorized , Token Miss found')
11 | }
12 | const isCustomAuth = token.length < 500;
13 | let decodedData;
14 |
15 | if (token && isCustomAuth) {
16 | decodedData = jwt.verify(token, process.env.JWT_SECRET_KEY)
17 | req.userId = decodedData?.id;
18 | } else {
19 | decodedData = jwt.decode(token)
20 | req.userId = decodedData?.sub;
21 | }
22 | next();
23 | } catch (err) {
24 | // res.status(401)
25 | res.status(401).send(err);
26 | throw new Error(err)
27 | }
28 | }
29 | module.exports = authMiddleware
--------------------------------------------------------------------------------
/server/middleware/ratelimiter.middleware.js:
--------------------------------------------------------------------------------
1 | const rateLimit = require('express-rate-limit');
2 |
3 | const rateLimiter = ({ windowMs, max, message }) => {
4 | return rateLimit({ windowMs, max, message });
5 | };
6 | module.exports = rateLimiter;
7 |
--------------------------------------------------------------------------------
/server/models/room.model.js:
--------------------------------------------------------------------------------
1 | const mongoose = require("mongoose");
2 |
3 | const Room = mongoose.model("Room", {
4 | room_id: {
5 | type: String,
6 | required: true,
7 | },
8 | room_title: {
9 | type: String,
10 | required: true,
11 | },
12 | room_body: {
13 | type: String,
14 | },
15 | room_language : {
16 | type : String
17 | },
18 | room_input : {
19 | type : String
20 | }
21 | });
22 |
23 | module.exports = Room;
24 |
--------------------------------------------------------------------------------
/server/models/user.modal.js:
--------------------------------------------------------------------------------
1 | const mongoose = require('mongoose');
2 | const jwt = require('jsonwebtoken');
3 |
4 | const userSchema = new mongoose.Schema({
5 | name: {
6 | type: String,
7 | required: true,
8 | },
9 | email: {
10 | type: String,
11 | required: true,
12 | },
13 | password: {
14 | type: String,
15 | required: true,
16 | },
17 | passwordChangedAt: Date,
18 | id: {
19 | type: String,
20 | },
21 | googleLogin: {
22 | type: Boolean,
23 | default: false,
24 | },
25 | imageUrl: {
26 | type: String,
27 | },
28 | });
29 |
30 | userSchema.methods.createPWDresetToken = async function () {
31 | return jwt.sign(
32 | { email: this.email, id: this._id },
33 | process.env.JWT_SECRET_KEY,
34 | { expiresIn: 600 }
35 | );
36 | };
37 |
38 | const User = mongoose.model('User', userSchema);
39 | module.exports = User;
40 |
--------------------------------------------------------------------------------
/server/routes/pwd.route.js:
--------------------------------------------------------------------------------
1 | const express = require('express');
2 | const rateLimiter = require('../middleware/ratelimiter.middleware');
3 |
4 | const forgotPasswordRateLimit = rateLimiter({
5 | windowMs: 10 * 60 * 1000,
6 | max: 1,
7 | message: 'Too many requests, please try again later for resetting password.',
8 | });
9 |
10 | const {
11 | forgotPwdController,
12 | resetPasswordController,
13 | } = require('../controllers/pwd.controllers');
14 |
15 | const router = express.Router();
16 |
17 | router.post('/_reset_password/:JWT_TOKEN', resetPasswordController);
18 | router.post('/_forgot_password', forgotPasswordRateLimit, forgotPwdController);
19 |
20 | module.exports = router;
21 |
--------------------------------------------------------------------------------
/server/routes/room.route.js:
--------------------------------------------------------------------------------
1 | const express = require("express");
2 | // TODO: Add middleware Route here
3 |
4 | const {
5 | createRoomById,
6 | getRoomByID,
7 | updateRoomById
8 | } = require("../controllers/room.controllers");
9 | const router = express.Router();
10 | const authMiddleware = require("../middleware/auth.middleware");
11 | // router.route("/").post(createRoomById);
12 | // router.route("/:id").get(getRoomByID).patch(updateRoomById);
13 | router.post('/', authMiddleware, createRoomById);
14 | router.get('/:id', authMiddleware, getRoomByID);
15 | router.patch('/:id', authMiddleware, updateRoomById);
16 |
17 | module.exports = router;
18 | // router.route('/:id').get();
19 |
--------------------------------------------------------------------------------
/server/routes/user.route.js:
--------------------------------------------------------------------------------
1 | const express = require("express");
2 | // TODO: Add middleware Route here
3 |
4 | const router = express.Router();
5 | const {
6 | LoginUser,
7 | registerUser,
8 | googleAuthUser
9 | } = require("../controllers/user.controllers");
10 |
11 | router.route("/register").post(registerUser);
12 | router.route("/login").post(LoginUser);
13 | router.route("/gauth").post(googleAuthUser);
14 |
15 |
16 |
17 |
18 | module.exports = router;
19 |
20 |
--------------------------------------------------------------------------------
/server/server.js:
--------------------------------------------------------------------------------
1 | const express = require('express')
2 | var colors = require('colors');
3 | const http = require('http')
4 | const connectDB = require('./config/db')
5 | const cors = require('cors')
6 | const dotenv = require('dotenv')
7 | var morgan = require('morgan')
8 | const path = require('path')
9 | var nodemailer = require('nodemailer');
10 | const axios = require('axios');
11 | const app = express()
12 | dotenv.config('../.env');
13 | const server = http.createServer(app);
14 | const port = process.env.PORT || 8080
15 | app.set('port', port);
16 | // DB Connection
17 | connectDB()
18 |
19 | // Production API LOG
20 |
21 | if (process.env.NODE_ENV === "development") {
22 | app.use(morgan("dev"));
23 | }
24 |
25 | // Middleware
26 | app.use(
27 | cors({
28 | credentials: true,
29 | origin: true,
30 | // methods: ["GET", "POST", "PUT", "PATCH"]
31 | })
32 | );
33 | app.use(express.json());
34 | // Controllers
35 | app.get("/", (req, res) => {
36 | res.send("API IS RUNNING")
37 | })
38 |
39 | app.use('/api',require('./routes/pwd.route'))
40 | app.use('/api/room/', require('./routes/room.route'));
41 | app.use('/api/user/', require('./routes/user.route'));
42 |
43 | // Socket.io
44 | const { Server, Socket } = require('socket.io');
45 | const { addUser, getUser, getUsersInRoom, removeUser } = require('./socket.user');
46 | const io = require('socket.io')(server, {
47 | cors: {
48 | origin: '*',
49 | // methods: ["GET", "POST","PUT","PATCH"]
50 | }
51 | });
52 |
53 | io.on('connection', (socket) => {
54 | let CentralRoomId = 0;
55 | let CentralUserName = "";
56 | let UserIdForRemove = '';
57 | socket.on('joinroom', async ({ roomId, userName, userImg }, callback) => {
58 | // console.log("Join ROom")
59 | const { error, user } = await addUser({ id: socket.id, name: userName, room: roomId, userImg });
60 | if (error) return callback(error);
61 | CentralRoomId = roomId;
62 | CentralUserName = userName
63 | UserIdForRemove = socket.id;
64 | socket.emit('message', { user: "Admin", text: `${userName}, Welcome to room ${roomId}` })
65 | socket.broadcast.to(roomId).emit('message', { user: "Admin", text: `${userName} has joined room!`, userImg: "zz" });
66 |
67 | socket.join(roomId);
68 |
69 | let users = getUsersInRoom(roomId)
70 | console.log("users", users)
71 | io.to(roomId).emit('numberOfUser', users);
72 |
73 | callback();
74 |
75 | });
76 | socket.on('sendMessage', (message, roomId) => {
77 | const user = getUser(socket.id);
78 | io.to(roomId).emit('message', { user: user.name, userImg: user.userImg, text: message })
79 | })
80 |
81 | socket.on('canvas-data', (data) => {
82 | // console.log(data, CentralRoomId)
83 | socket.broadcast.to(CentralRoomId).emit('canvas-data', data);
84 |
85 | })
86 | socket.on('updateBody', ({ value, roomId }) => {
87 | socket.broadcast.to(roomId).emit('updateBody', value);
88 | });
89 | socket.on('updateInput', ({ value, roomId }) => {
90 | socket.broadcast.to(roomId).emit('updateInput', value);
91 | });
92 | socket.on('updateLanguage', ({ value, roomId }) => {
93 | // console.log({ value, roomId })
94 | socket.broadcast.to(roomId).emit('updateLanguage', value);
95 | });
96 | socket.on('updateOutput', ({ value, roomId }) => {
97 | socket.broadcast.to(roomId).emit('updateOutput', value);
98 | });
99 | socket.on('updateRichText', ({ value, roomId }) => {
100 | socket.broadcast.to(roomId).emit('updateRichText', value);
101 | });
102 |
103 | socket.on('joinAudioRoom', (roomId, userId) => {
104 | // console.log({ roomId, userId });
105 | socket.broadcast.to(roomId).emit('userJoinedAudio', userId);
106 |
107 | socket.on('leaveAudioRoom', () => {
108 | socket.broadcast.to(roomId).emit('userLeftAudio', userId);
109 | });
110 | });
111 | socket.on('disconnect', ({ userName }) => {
112 | const user = removeUser(UserIdForRemove)
113 | let users = getUsersInRoom(CentralRoomId)
114 | console.log("users", user)
115 | io.to(CentralRoomId).emit('numberOfUser', users);
116 | console.log("User disconnect");
117 | })
118 | });
119 |
120 |
121 |
122 | var transporter = nodemailer.createTransport({
123 | service: 'gmail',
124 | auth: {
125 | user: process.env.OUR_EMAIL,
126 | pass: process.env.EMAIL_PASS
127 | },
128 | from : "codesync.live"
129 | });
130 |
131 |
132 |
133 | app.post('/sendMail', (req, res) => {
134 | const { sendTo ,mailSubject , roomLink , userName ,userEmail} = req.body
135 | var options = {
136 | method: 'POST',
137 | url: process.env.EMAIL_API_URL,
138 | headers: {
139 | 'content-type': 'application/json',
140 | 'x-rapidapi-host': process.env.EMAIL_API_HOST,
141 | 'x-rapidapi-key': process.env.EMAIL_API_KEY
142 | },
143 | data: {
144 | personalizations: [{to: [{email: sendTo}], subject: mailSubject}],
145 | from: {email: 'codesync.live@gmail.com'},
146 | content: [{type: 'text/html', value: `Hello Dear, ${userName} is invite you on CodeSync for write collaboration code. Click here to Join the room
`}]
147 | }
148 | };
149 |
150 | axios.request(options).then(function (response) {
151 | // console.log();
152 | res.status(200).send("Mail sent successfully.")
153 | }).catch(function (error) {
154 | console.error(error);
155 | res.send("Something went wrong")
156 | });
157 | })
158 |
159 |
160 | // Production Settings
161 | // if (process.env.NODE_ENV === 'production') {
162 | // // Set Value
163 | // app.use(express.static(path.join(__dirname, '/client/build')))
164 |
165 | // app.get('*', (req, res) => {
166 | // res.sendFile(path.resolve(__dirname,'..', 'client', 'build', 'index.html'));
167 | // })
168 |
169 | // }
170 | server.listen(port, () => {
171 | console.log(`Example app listening at http://localhost:${port}`)
172 | })
173 |
--------------------------------------------------------------------------------
/server/socket.user.js:
--------------------------------------------------------------------------------
1 | const users = [];
2 |
3 | const addUser = ({ id, name, room , userImg}) => {
4 | name = name.trim().toLowerCase();
5 | room = room.trim().toLowerCase();
6 |
7 | const existingUser = users.find((user) => user.room === room && user.name === name);
8 |
9 | if (!name || !room) return { error: 'Username and room are required.' };
10 | if (existingUser) return { error: 'Username is taken.' };
11 |
12 | const user = { id, name, room, userImg};
13 |
14 | users.push(user);
15 | return { user };
16 | }
17 |
18 | const removeUser = (id) => {
19 | const index = users.findIndex((user) => user.id === id);
20 | if (index !== -1) return users.splice(index, 1)[0];
21 | }
22 |
23 | const getUser = (id) => users.find((user) => user.id === id);
24 |
25 | const getUsersInRoom = (room) => users.filter((user) => user.room === room);
26 |
27 | module.exports = { addUser, removeUser, getUser, getUsersInRoom };
--------------------------------------------------------------------------------