Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 41 additions & 0 deletions App.tsx
Original file line number Diff line number Diff line change
@@ -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 (
<div>
<h1>Vi-Notes</h1>
<textarea
value={text}
onChange={handleChange}
rows={10}
cols={50}
placeholder="start writing here..."
/>
<br />
<p>word count: {text.split(' ').filter(w => w != '').length}</p>
<button onClick={saveText}>Save</button>
<p>{msg}</p>
</div>
)
}

export default Editor
68 changes: 68 additions & 0 deletions server.ts
Original file line number Diff line number Diff line change
@@ -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()
59 changes: 59 additions & 0 deletions src/App.tsx
Original file line number Diff line number Diff line change
@@ -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 <Login onLogin={handleLogin} onRegister={() => setPage('register')} />
}

if (page == 'register') {
return <Register onDone={() => setPage('login')} />
}

return (
<div>
<h1>Vi-Notes</h1>
<textarea
value={text}
onChange={handleChange}
rows={10}
cols={50}
placeholder="start writing here..."
/>
<br />
<p>word count: {text.split(' ').filter(w => w != '').length}</p>
<button onClick={saveText}>Save</button>
<p>{msg}</p>
<button onClick={() => setPage('login')}>Logout</button>
</div>
)
}

export default App
54 changes: 54 additions & 0 deletions src/Login.tsx
Original file line number Diff line number Diff line change
@@ -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 (
<div>
<h1>Vi-Notes</h1>
<h2>Login</h2>
<input
placeholder="email"
value={e}
onChange={(ev) => setE(ev.target.value)}
/>
<br />
<input
placeholder="password"
type="password"
value={p}
onChange={(ev) => setP(ev.target.value)}
/>
<br />
<button onClick={doLogin}>Login</button>
<p>{msg}</p>
<p>no account? <button onClick={props.onRegister}>register here</button></p>
</div>
)
}

export default Login
73 changes: 73 additions & 0 deletions src/Register.tsx
Original file line number Diff line number Diff line change
@@ -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 (
<div>
<h1>Vi-Notes</h1>
<h2>Register</h2>
<input
placeholder="name"
value={n}
onChange={(ev) => setN(ev.target.value)}
/>
<br />
<input
placeholder="email"
value={e}
onChange={(ev) => setE(ev.target.value)}
/>
<br />
<input
placeholder="password"
type="password"
value={p}
onChange={(ev) => setP(ev.target.value)}
/>
<br />
<input
placeholder="confirm password"
type="password"
value={p2}
onChange={(ev) => setP2(ev.target.value)}
/>
<br />
<button onClick={doRegister}>Register</button>
<p>{msg}</p>
<p>already have an account? <button onClick={props.onDone}>login here</button></p>
</div>
)
}

export default Register