diff --git a/App.tsx b/App.tsx
new file mode 100644
index 000000000..e2fdb4f3e
--- /dev/null
+++ b/App.tsx
@@ -0,0 +1,41 @@
+import { useState } from 'react'
+
+function Editor() {
+ const [text, setText] = useState('')
+ const [msg, setMsg] = useState('')
+
+ function handleChange(e: any) {
+ setText(e.target.value)
+ }
+
+ async function saveText() {
+ const res = await fetch('http://localhost:3000/save', {
+ method: 'POST',
+ headers: { 'Content-Type': 'application/json' },
+ body: JSON.stringify({ text: text })
+ })
+ const data = await res.json()
+ if (data.msg == 'saved') {
+ setMsg('saved!')
+ }
+ }
+
+ return (
+
+
Vi-Notes
+
+
+
word count: {text.split(' ').filter(w => w != '').length}
+
+
{msg}
+
+ )
+}
+
+export default Editor
\ No newline at end of file
diff --git a/server.ts b/server.ts
new file mode 100644
index 000000000..fec231503
--- /dev/null
+++ b/server.ts
@@ -0,0 +1,68 @@
+import express from 'express'
+import cors from 'cors'
+import { MongoClient } from 'mongodb'
+
+const app = express()
+app.use(cors())
+app.use(express.json())
+
+const url = 'mongodb+srv://arnabacharya1612_db_use:test123@ac-wzo6xjz.8peoruq.mongodb.net/?retryWrites=true&w=majority'
+const client = new MongoClient(url)
+
+async function start() {
+ await client.connect()
+ console.log('connected to mongodb')
+
+ const db = client.db('vinotes')
+
+ // register
+ app.post('/register', async (req, res) => {
+ const n = req.body.name
+ const e = req.body.email
+ const p = req.body.password
+
+ const found = await db.collection('users').find({ email: e }).toArray()
+ if (found.length > 0) {
+ res.json({ msg: 'user already exists' })
+ return
+ }
+
+ await db.collection('users').insertOne({ name: n, email: e, password: p })
+ console.log('new user registered')
+ res.json({ msg: 'registered ok' })
+ })
+
+ // login
+ app.post('/login', async (req, res) => {
+ const e = req.body.email
+ const p = req.body.password
+
+ const found = await db.collection('users').find({ email: e, password: p }).toArray()
+ if (found.length == 0) {
+ res.json({ msg: 'wrong email or password' })
+ return
+ }
+
+ console.log('user logged in')
+ res.json({ msg: 'login ok', userId: found[0]._id })
+ })
+
+ // save note
+ app.post('/save', async (req, res) => {
+ try {
+ const t = req.body.text
+ const u = req.body.userId
+ await db.collection('notes').insertOne({ text: t, userId: u, savedAt: new Date() })
+ res.json({ msg: 'saved' })
+ } catch (err) {
+ console.log(err)
+ res.status(500).json({ msg: 'error' })
+ }
+ })
+
+ app.listen(3000, () => {
+ console.log('server running on port 3000')
+ })
+}
+
+start()
diff --git a/src/App.tsx b/src/App.tsx
new file mode 100644
index 000000000..d122c09bb
--- /dev/null
+++ b/src/App.tsx
@@ -0,0 +1,59 @@
+import { useState } from 'react'
+import Login from './Login'
+import Register from './Register'
+
+function App() {
+ const [page, setPage] = useState('login')
+ const [uid, setUid] = useState('')
+ const [text, setText] = useState('')
+ const [msg, setMsg] = useState('')
+
+ function handleLogin(id: string) {
+ setUid(id)
+ setPage('editor')
+ }
+
+ function handleChange(e: any) {
+ setText(e.target.value)
+ }
+
+ async function saveText() {
+ const res = await fetch('http://localhost:3000/save', {
+ method: 'POST',
+ headers: { 'Content-Type': 'application/json' },
+ body: JSON.stringify({ text: text, userId: uid })
+ })
+ const data = await res.json()
+ if (data.msg == 'saved') {
+ setMsg('saved!')
+ }
+ }
+
+ if (page == 'login') {
+ return setPage('register')} />
+ }
+
+ if (page == 'register') {
+ return setPage('login')} />
+ }
+
+ return (
+
+
Vi-Notes
+
+
+
word count: {text.split(' ').filter(w => w != '').length}
+
+
{msg}
+
+
+ )
+}
+
+export default App
diff --git a/src/Login.tsx b/src/Login.tsx
new file mode 100644
index 000000000..05a9cec9d
--- /dev/null
+++ b/src/Login.tsx
@@ -0,0 +1,54 @@
+import { useState } from 'react'
+
+function Login(props: any) {
+ const [e, setE] = useState('')
+ const [p, setP] = useState('')
+ const [msg, setMsg] = useState('')
+
+ async function doLogin() {
+ if (e == '' || p == '') {
+ setMsg('please fill all fields')
+ return
+ }
+
+ const res = await fetch('http://localhost:3000/login', {
+ method: 'POST',
+ headers: { 'Content-Type': 'application/json' },
+ body: JSON.stringify({ email: e, password: p })
+ })
+
+ const data = await res.json()
+ console.log(data)
+
+ if (data.msg == 'login ok') {
+ props.onLogin(data.userId)
+ } else {
+ setMsg(data.msg)
+ }
+ }
+
+ return (
+
+
Vi-Notes
+
Login
+
setE(ev.target.value)}
+ />
+
+
setP(ev.target.value)}
+ />
+
+
+
{msg}
+
no account?
+
+ )
+}
+
+export default Login
diff --git a/src/Register.tsx b/src/Register.tsx
new file mode 100644
index 000000000..3253f5015
--- /dev/null
+++ b/src/Register.tsx
@@ -0,0 +1,73 @@
+import { useState } from 'react'
+
+function Register(props: any) {
+ const [n, setN] = useState('')
+ const [e, setE] = useState('')
+ const [p, setP] = useState('')
+ const [p2, setP2] = useState('')
+ const [msg, setMsg] = useState('')
+
+ async function doRegister() {
+ if (n == '' || e == '' || p == '') {
+ setMsg('please fill all fields')
+ return
+ }
+
+ if (p != p2) {
+ setMsg('passwords do not match')
+ return
+ }
+
+ const res = await fetch('http://localhost:3000/register', {
+ method: 'POST',
+ headers: { 'Content-Type': 'application/json' },
+ body: JSON.stringify({ name: n, email: e, password: p })
+ })
+
+ const data = await res.json()
+ console.log(data)
+ setMsg(data.msg)
+
+ if (data.msg == 'registered ok') {
+ props.onDone()
+ }
+ }
+
+ return (
+
+
Vi-Notes
+
Register
+
setN(ev.target.value)}
+ />
+
+
setE(ev.target.value)}
+ />
+
+
setP(ev.target.value)}
+ />
+
+
setP2(ev.target.value)}
+ />
+
+
+
{msg}
+
already have an account?
+
+ )
+}
+
+export default Register