Skip to content

Commit ddcb600

Browse files
committed
upload files
0 parents  commit ddcb600

18 files changed

+1991
-0
lines changed

client/.gitignore

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# Logs
2+
logs
3+
*.log
4+
npm-debug.log*
5+
yarn-debug.log*
6+
yarn-error.log*
7+
pnpm-debug.log*
8+
lerna-debug.log*
9+
10+
node_modules
11+
dist
12+
dist-ssr
13+
*.local
14+
15+
# Editor directories and files
16+
.vscode/*
17+
!.vscode/extensions.json
18+
.idea
19+
.DS_Store
20+
*.suo
21+
*.ntvs*
22+
*.njsproj
23+
*.sln
24+
*.sw?

client/index.html

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8" />
5+
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
6+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
7+
<title>Vite + React</title>
8+
</head>
9+
<body>
10+
<div id="root"></div>
11+
<script type="module" src="/src/main.jsx"></script>
12+
</body>
13+
</html>

client/package-lock.json

+1,553
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

client/package.json

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
{
2+
"name": "client",
3+
"private": true,
4+
"version": "0.0.0",
5+
"type": "module",
6+
"scripts": {
7+
"dev": "vite",
8+
"build": "vite build",
9+
"preview": "vite preview"
10+
},
11+
"dependencies": {
12+
"@emotion/react": "^11.10.0",
13+
"@emotion/styled": "^11.10.0",
14+
"@mui/material": "^5.10.1",
15+
"quill": "^1.3.7",
16+
"react": "^18.2.0",
17+
"react-dom": "^18.2.0",
18+
"react-router-dom": "^6.3.0",
19+
"socket.io-client": "^4.5.1",
20+
"uuid": "^8.3.2"
21+
},
22+
"devDependencies": {
23+
"@types/react": "^18.0.17",
24+
"@types/react-dom": "^18.0.6",
25+
"@vitejs/plugin-react": "^2.0.1",
26+
"vite": "^3.0.7"
27+
}
28+
}

client/public/vite.svg

+1
Loading

client/src/App.css

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
2+
3+
.container{
4+
width: 60%;
5+
background: #fff;
6+
box-shadow: 0 0 5px 0 rgba(0, 0, 0, 0.5);
7+
margin: 10px auto 10px auto !important;
8+
min-height: 100vh;
9+
10+
}
11+
12+
.ql-toolbar.ql-snow {
13+
display: flex;
14+
justify-content: center;
15+
position: sticky;
16+
top: 0;
17+
z-index: 1;
18+
background: #F3F3F3;
19+
border: none !important;
20+
box-shadow: 0 0 5px 0 rgba(0, 0, 0, 0.5);
21+
}
22+
23+
.ql-snow .ql-editor img{
24+
width: 800px;
25+
height: 400px;
26+
object-fit: contain;
27+
}

client/src/App.jsx

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import "./App.css";
2+
import Editor from "./components/Editor";
3+
import { BrowserRouter, Routes, Route, Navigate } from "react-router-dom";
4+
import {v4 as uuid} from "uuid";
5+
6+
function App() {
7+
return (
8+
<BrowserRouter>
9+
<Routes>
10+
<Route path="/" element={<Navigate replace to={`/docs/${uuid()}`}/> } />
11+
<Route path="/docs/:id" element={<Editor />} />
12+
</Routes>
13+
</BrowserRouter>
14+
);
15+
}
16+
17+
export default App;

client/src/assets/react.svg

+1
Loading

client/src/components/Editor.jsx

+126
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
import Quill from "quill";
2+
import "quill/dist/quill.snow.css";
3+
4+
import {Box} from "@mui/material";
5+
import { useEffect, useState } from "react";
6+
7+
import styled from "@emotion/styled";
8+
9+
import {io} from "socket.io-client";
10+
import { useParams } from "react-router-dom";
11+
12+
13+
const Component = styled.div`
14+
background: #F5F5F5;
15+
`
16+
17+
const toolbarOptions = [
18+
['bold', 'italic', 'underline', 'strike'], // toggled buttons
19+
['blockquote', 'code-block'],
20+
21+
[{ 'header': 1 }, { 'header': 2 }], // custom button values
22+
[{ 'list': 'ordered'}, { 'list': 'bullet' }],
23+
[{ 'script': 'sub'}, { 'script': 'super' }], // superscript/subscript
24+
[{ 'indent': '-1'}, { 'indent': '+1' }], // outdent/indent
25+
[{ 'direction': 'rtl' }], // text direction
26+
27+
[{ 'size': ['small', false, 'large', 'huge'] }], // custom dropdown
28+
[{ 'header': [1, 2, 3, 4, 5, 6, false] }],
29+
['link', 'image'],
30+
[{ 'color': [] }, { 'background': [] }], // dropdown with defaults from theme
31+
[{ 'font': [] }],
32+
[{ 'align': [] }],
33+
34+
['clean'] // remove formatting button
35+
];
36+
37+
38+
const Editor = () => {
39+
40+
const [socket, setSocket] = useState();
41+
const [quill, setQuill] = useState();
42+
const {id} = useParams();
43+
44+
useEffect(() => {
45+
const quillserver = new Quill('#container', { theme: 'snow', modules: { toolbar: toolbarOptions}});
46+
quillserver.disable();
47+
quillserver.setText('Loading the Document ...')
48+
setQuill(quillserver);
49+
},[])
50+
51+
useEffect(() => {
52+
const socketServer = io('http://localhost:9000');
53+
setSocket(socketServer);
54+
return () => {
55+
socketServer.disconnect();
56+
}
57+
},[])
58+
59+
useEffect(() => {
60+
61+
if (socket === null || quill === null) return;
62+
63+
const handleChange = (delta, oldData, source) => {
64+
if(source !== 'user') return;
65+
66+
socket && socket.emit('send-changes', delta);
67+
68+
}
69+
70+
quill && quill.on('text-change',handleChange);
71+
72+
return () => {
73+
quill && quill.off('text-change', handleChange);
74+
}
75+
},[quill, socket]);
76+
77+
78+
useEffect(() => {
79+
80+
if (socket === null || quill === null) return;
81+
82+
const handleChange = (delta) => {
83+
84+
quill.updateContents(delta);
85+
86+
}
87+
88+
socket && socket.on('receive-changes',handleChange);
89+
90+
return () => {
91+
socket && socket.off('receive-changes', handleChange);
92+
}
93+
},[quill, socket]);
94+
95+
useEffect(() => {
96+
if (socket === null || quill === null) return;
97+
98+
socket && socket.once('load-document', document => {
99+
quill && quill.setContents(document);
100+
quill && quill.enable();
101+
})
102+
103+
socket && socket.emit('get-document', id)
104+
}, [quill, socket, id]);
105+
106+
useEffect(() => {
107+
if (socket === null || quill === null) return;
108+
109+
const interval = setInterval(() => {
110+
socket && socket.emit('save-document', quill.getContents())
111+
}, 2000);
112+
113+
return () => {
114+
clearInterval(interval);
115+
}
116+
}, [socket, quill]);
117+
118+
return (
119+
<Component>
120+
<Box className='container' id='container'></Box>
121+
</Component>
122+
123+
)
124+
}
125+
126+
export default Editor

client/src/index.css

+84
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
/* :root {
2+
font-family: Inter, Avenir, Helvetica, Arial, sans-serif;
3+
font-size: 16px;
4+
line-height: 24px;
5+
font-weight: 400;
6+
7+
color-scheme: light dark;
8+
color: rgba(255, 255, 255, 0.87);
9+
background-color: #242424;
10+
11+
font-synthesis: none;
12+
text-rendering: optimizeLegibility;
13+
-webkit-font-smoothing: antialiased;
14+
-moz-osx-font-smoothing: grayscale;
15+
-webkit-text-size-adjust: 100%;
16+
}
17+
18+
a {
19+
font-weight: 500;
20+
color: #646cff;
21+
text-decoration: inherit;
22+
}
23+
a:hover {
24+
color: #535bf2;
25+
}
26+
27+
body {
28+
margin: 0;
29+
display: flex;
30+
place-items: center;
31+
min-width: 320px;
32+
min-height: 100vh;
33+
}
34+
35+
h1 {
36+
font-size: 3.2em;
37+
line-height: 1.1;
38+
}
39+
40+
button {
41+
border-radius: 8px;
42+
border: 1px solid transparent;
43+
padding: 0.6em 1.2em;
44+
font-size: 1em;
45+
font-weight: 500;
46+
font-family: inherit;
47+
background-color: #1a1a1a;
48+
cursor: pointer;
49+
transition: border-color 0.25s;
50+
}
51+
button:hover {
52+
border-color: #646cff;
53+
}
54+
button:focus,
55+
button:focus-visible {
56+
outline: 4px auto -webkit-focus-ring-color;
57+
}
58+
59+
@media (prefers-color-scheme: light) {
60+
:root {
61+
color: #213547;
62+
background-color: #ffffff;
63+
}
64+
a:hover {
65+
color: #747bff;
66+
}
67+
button {
68+
background-color: #f9f9f9;
69+
}
70+
} */
71+
72+
body {
73+
margin: 0;
74+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
75+
'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
76+
sans-serif;
77+
-webkit-font-smoothing: antialiased;
78+
-moz-osx-font-smoothing: grayscale;
79+
}
80+
81+
code {
82+
font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
83+
monospace;
84+
}

client/src/main.jsx

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import React from 'react'
2+
import ReactDOM from 'react-dom/client'
3+
import App from './App'
4+
import './index.css'
5+
6+
ReactDOM.createRoot(document.getElementById('root')).render(
7+
// <React.StrictMode>
8+
<App />
9+
// {/* </React.StrictMode> */}
10+
)

client/vite.config.js

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import { defineConfig } from 'vite'
2+
import react from '@vitejs/plugin-react'
3+
4+
// https://vitejs.dev/config/
5+
export default defineConfig({
6+
plugins: [react()]
7+
})

server/.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
node_modules
2+
package-lock.json
+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import Document from "../model/documentSchema.js";
2+
3+
export const getDocument = async (id) => {
4+
if(id === null) return;
5+
6+
const document = await Document.findById(id);
7+
8+
if(document) return document;
9+
10+
return await Document.create({_id: id, data: ""});
11+
}
12+
13+
14+
export const updateDocument = async (id, data) => {
15+
return await Document.findByIdAndUpdate(id, {data});
16+
}

server/database/db.js

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import mongoose from "mongoose";
2+
3+
const Connection = async (username = 'prince', password = 'prince123') => {
4+
const URL = `mongodb+srv://${username}:${password}@cluster0.wmjmq.mongodb.net/googledoc?retryWrites=true&w=majority`
5+
try {
6+
await mongoose.connect(URL, {useUnifiedTopology: true, useNewurlParser: true});
7+
console.log('Database connected successfully');
8+
} catch (error) {
9+
console.log('Erroe while connecting database', error);
10+
}
11+
}
12+
13+
export default Connection;

0 commit comments

Comments
 (0)