Skip to content

SavePassword Function Fix #269

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
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
280 changes: 133 additions & 147 deletions Video 130/passop-mongo/src/components/Manager.jsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,18 @@
import React from 'react'
import { useRef, useState, useEffect } from 'react';
import { ToastContainer, toast } from 'react-toastify';
import { useRef, useState, useEffect } from 'react'
import { ToastContainer, toast } from 'react-toastify'
import 'react-toastify/dist/ReactToastify.css'
import { v4 as uuidv4 } from 'uuid';
import 'react-toastify/dist/ReactToastify.css';

const Manager = () => {
const ref = useRef()
const passwordRef = useRef()
const [form, setform] = useState({ site: "", username: "", password: "" })
const [form, setform] = useState({ site: '', username: '', password: '' })
const [passwordArray, setPasswordArray] = useState([])

const getPasswords = async () => {
let req = await fetch("http://localhost:3000/")
let req = await fetch('http://localhost:3000/')
let passwords = await req.json()
setPasswordArray(passwords)
setPasswordArray(passwords);
}


Expand All @@ -22,191 +21,179 @@ const Manager = () => {
}, [])


const copyText = (text) => {
toast('Copied to clipboard!', {
position: "top-right",
autoClose: 5000,
hideProgressBar: false,
closeOnClick: true,
pauseOnHover: true,
draggable: true,
progress: undefined,
theme: "dark",
});
navigator.clipboard.writeText(text)
const handleChange = (e) => {
setform({ ...form, [e.target.name]: e.target.value })
}

const showPassword = () => {
passwordRef.current.type = "text"
console.log(ref.current.src)
if (ref.current.src.includes("icons/eyecross.png")) {
ref.current.src = "icons/eye.png"
passwordRef.current.type = "password"
}
else {
passwordRef.current.type = "text"
ref.current.src = "icons/eyecross.png"
if (ref.current.src.includes("/crosseye.svg")) {
ref.current.src = "/eye.svg"
passwordRef.current.type = 'password'
} else {
ref.current.src = "/crosseye.svg"
passwordRef.current.type = 'text'
}

}

const savePassword = async () => {
if (form.site.length > 3 && form.username.length > 3 && form.password.length > 3) {

// If any such id exists in the db, delete it
await fetch("http://localhost:3000/", { method: "DELETE", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ id: form.id }) })

setPasswordArray([...passwordArray, { ...form, id: uuidv4() }])
await fetch("http://localhost:3000/", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ ...form, id: uuidv4() }) })

// Otherwise clear the form and show toast
setform({ site: "", username: "", password: "" })
toast('Password saved!', {
if (form.site === '' || form.username === '' || form.password === '') {
toast.error('Please fill all fields!', {
position: "top-right",
autoClose: 5000,
hideProgressBar: false,
closeOnClick: true,
pauseOnHover: true,
draggable: true,
progress: undefined,
theme: "dark",
theme: "light",
});
return;
}
else {
toast('Error: Password not saved!');
setPasswordArray([...passwordArray, { ...form, id: uuidv4() }])
//while editing delete the old password
if (form.id) { // Changed from form.ide to form.id
await fetch("http://localhost:3000/", {
method: 'DELETE',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ id: form.id })
})
}

// localStorage.setItem('passwords', JSON.stringify([...passwordArray, { ...form, id: uuidv4() }]))
await fetch("http://localhost:3000/", {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ ...form, id: uuidv4() })
})
setform({ site: '', username: '', password: '' })
toast.success('Password saved successfully!', {
position: "top-right",
autoClose: 5000,
hideProgressBar: false,
closeOnClick: true,
pauseOnHover: true,
draggable: true,
progress: undefined,
theme: "light",
});
}

const deletePassword = async (id) => {
console.log("Deleting password with id ", id)
let c = confirm("Do you really want to delete this password?")
if (c) {
setPasswordArray(passwordArray.filter(item => item.id !== id))

await fetch("http://localhost:3000/", { method: "DELETE", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ id }) })

toast('Password Deleted!', {
position: "top-right",
autoClose: 5000,
hideProgressBar: false,
closeOnClick: true,
draggable: true,
progress: undefined,
theme: "dark",
});
}

let confirmDelete = window.confirm("Are you sure you want to delete this password?");
if (!confirmDelete) return;
setPasswordArray(passwordArray.filter((item) => item.id !== id))
// localStorage.setItem('passwords', JSON.stringify(passwordArray.filter((item) => item.id !== id)))
let res = await fetch("http://localhost:3000/", {
method: 'DELETE',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ id: id })
})

toast.error('Password deleted successfully!', {
position: "top-right",
autoClose: 5000,
hideProgressBar: false,
closeOnClick: true,
pauseOnHover: true,
draggable: true,
progress: undefined,
theme: "light",
});
}

const editPassword = (id) => {
setform({ ...passwordArray.filter(i => i.id === id)[0], id: id })
setPasswordArray(passwordArray.filter(item => item.id !== id))
}


const handleChange = (e) => {
setform({ ...form, [e.target.name]: e.target.value })
setform({
...passwordArray.find((item) => item.id === id),
id: id // keep the id same for editing
})
setPasswordArray(passwordArray.filter((item) => item.id !== id))
}


return (
<>
<ToastContainer />
<div className="absolute inset-0 -z-10 h-full w-full bg-green-50 bg-[linear-gradient(to_right,#8080800a_1px,transparent_1px),linear-gradient(to_bottom,#8080800a_1px,transparent_1px)] bg-[size:14px_24px]"><div className="absolute left-0 right-0 top-0 -z-10 m-auto h-[310px] w-[310px] rounded-full bg-green-400 opacity-20 blur-[100px]"></div></div>
<div className=" p-3 md:mycontainer min-h-[88.2vh] ">
<ToastContainer
position="top-right"
autoClose={5000}
hideProgressBar={false}
newestOnTop={false}
closeOnClick={false}
rtl={false}
pauseOnFocusLoss
draggable
pauseOnHover
theme="light"
/>

<div className="absolute inset-0 -z-10 h-full w-full bg-white bg-[linear-gradient(to_right,#f0f0f0_1px,transparent_1px),linear-gradient(to_bottom,#f0f0f0_1px,transparent_1px)] bg-[size:6rem_4rem]"></div>
<div className="md:mycontainer">
<h1 className='text-4xl text font-bold text-center'>
<span className='text-green-500'> &lt;</span>

<span>Pass</span><span className='text-green-500'>OP/&gt;</span>
<span className="text-green-700">&lt;</span>
Pass
<span className='text-[#FFD700] text-5xl'>Vault</span>
<span className="text-green-700">/&gt;</span>

</h1>
<p className='text-green-900 text-lg text-center'>Your own Password Manager</p>

<div className="flex flex-col p-4 text-black gap-8 items-center">
<input value={form.site} onChange={handleChange} placeholder='Enter website URL' className='rounded-full border border-green-500 w-full p-4 py-1' type="text" name="site" id="site" />
<div className="flex flex-col md:flex-row w-full justify-between gap-8">
<input value={form.username} onChange={handleChange} placeholder='Enter Username' className='rounded-full border border-green-500 w-full p-4 py-1' type="text" name="username" id="username" />
<div className="relative">
<input ref={passwordRef} value={form.password} onChange={handleChange} placeholder='Enter Password' className='rounded-full border border-green-500 w-full p-4 py-1' type="password" name="password" id="password" />
<span className='absolute right-[3px] top-[4px] cursor-pointer' onClick={showPassword}>
<img ref={ref} className='p-1' width={26} src="icons/eye.png" alt="eye" />
</span>
<p className='text-yellow-400 text-lg text-center'>Your own password manager</p>

<div className="text-black flex flex-col p-4 gap-5">
<input value={form.site} onChange={handleChange} placeholder='Enter Your Website Name' className='rounded-full border border-yellow-400 w-full p-4 py-1' type="text" name="site" id="site-name" />
<div className="flex gap-8">
<input value={form.username} onChange={handleChange} placeholder='Enter Your User Name' className='rounded-full border border-yellow-400 w-full p-4 py-1' type="text" name="username" id="user-name" />
<div className='relative w-full'>
<input ref={passwordRef} value={form.password} onChange={handleChange} placeholder='Enter Your Password' className='rounded-full border border-yellow-400 w-full p-4 py-1' type="password" name="password" id="user-password" />
<span className='absolute right-2 top-0'><img ref={ref} className='p-1 cursor-pointer' onClick={showPassword} width={34} src="/eye.svg" alt="" /></span>
</div>

</div>
<button onClick={savePassword} className='flex justify-center items-center gap-2 bg-green-400 hover:bg-green-300 rounded-full px-8 py-2 w-fit border border-green-900'>
<lord-icon
src="https://cdn.lordicon.com/jgnvfzqg.json"
trigger="hover" >
</lord-icon>
Save</button>
<div className='items-center flex flex-col'>
<button onClick={savePassword} className='border-blue-600 border flex justify-center items-center rounded-full text-black px-2 py-2 gap-2 w-48 transition-all duration-300 bg-blue-300 hover:bg-blue-400'>
<lord-icon
src="https://cdn.lordicon.com/gzqofmcx.json"
trigger="hover">
</lord-icon>
Save Password
</button>
</div>
</div>

<div className="passwords">
<h2 className='font-bold text-2xl py-4'>Your Passwords</h2>
{passwordArray.length === 0 && <div> No passwords to show</div>}
{passwordArray.length != 0 && <table className="table-auto w-full rounded-md overflow-hidden mb-10">
<thead className='bg-green-800 text-white'>
{passwordArray.length === 0 && <div>No passwords Found</div>}

{passwordArray.length !== 0 && <table className="table-auto w-full overflow-hidden rounded-lg border border-yellow-400">
<thead className='bg-yellow-400 text-black'>
<tr>
<th className='py-2'>Site</th>
<th className='py-2'>Username</th>
<th className='py-2'>Password</th>
<th className='py-2'>Site Name</th>
<th className='py-2'>User Name</th>
<th className='py-2'>User Password</th>
<th className='py-2'>Actions</th>
</tr>
</thead>
<tbody className='bg-green-100'>
<tbody className='bg-yellow-100 text-black'>
{passwordArray.map((item, index) => {
return <tr key={index}>
<td className='py-2 border border-white text-center'>
<div className='flex items-center justify-center '>
<a href={item.site} target='_blank'>{item.site}</a>
<div className='lordiconcopy size-7 cursor-pointer' onClick={() => { copyText(item.site) }}>
<lord-icon
style={{ "width": "25px", "height": "25px", "paddingTop": "3px", "paddingLeft": "3px" }}
src="https://cdn.lordicon.com/iykgtsbt.json"
trigger="hover" >
</lord-icon>
</div>
</div>
</td>
<td className='py-2 border border-white text-center'>
<div className='flex items-center justify-center '>
<span>{item.username}</span>
<div className='lordiconcopy size-7 cursor-pointer' onClick={() => { copyText(item.username) }}>
<lord-icon
style={{ "width": "25px", "height": "25px", "paddingTop": "3px", "paddingLeft": "3px" }}
src="https://cdn.lordicon.com/iykgtsbt.json"
trigger="hover" >
</lord-icon>
</div>
</div>
</td>
<td className='py-2 border border-white text-center'>
<div className='flex items-center justify-center '>
<span>{"*".repeat(item.password.length)}</span>
<div className='lordiconcopy size-7 cursor-pointer' onClick={() => { copyText(item.password) }}>
<lord-icon
style={{ "width": "25px", "height": "25px", "paddingTop": "3px", "paddingLeft": "3px" }}
src="https://cdn.lordicon.com/iykgtsbt.json"
trigger="hover" >
</lord-icon>
</div>
</div>
</td>
<td className='justify-center py-2 border border-white text-center'>
<span className='cursor-pointer mx-1' onClick={() => { editPassword(item.id) }}>
<td className='border py-2 text-center w-32'>{item.site}</td>
<td className='border py-2 text-center w-32'>{item.username}</td>
<td className='border py-2 text-center w-32'>{item.password}</td>
<td className='border py-2 text-center w-32'>
<span className='cursor-pointer mx-1' onClick={() => {
editPassword(item.id)
}}>
<lord-icon
src="https://cdn.lordicon.com/gwlusjdu.json"
src="https://cdn.lordicon.com/fikcyfpp.json"
trigger="hover"
style={{ "width": "25px", "height": "25px" }}>
stroke="bold">
</lord-icon>
</span>
<span className='cursor-pointer mx-1' onClick={() => { deletePassword(item.id) }}>
<span className='cursor-pointer mx-1' onClick={() => {
deletePassword(item.id)
}}>
<lord-icon
src="https://cdn.lordicon.com/skkahier.json"
trigger="hover"
style={{ "width": "25px", "height": "25px" }}>
src="https://cdn.lordicon.com/oqeixref.json"
trigger="hover">
</lord-icon>
</span>
</td>
Expand All @@ -216,7 +203,6 @@ const Manager = () => {
</table>}
</div>
</div>

</>
)
}
Expand Down