create-exam-cli 1.0.2 → 1.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/index.js
CHANGED
|
@@ -4,16 +4,16 @@ const inquirer = require("inquirer")
|
|
|
4
4
|
const fs = require("fs-extra")
|
|
5
5
|
const path = require("path")
|
|
6
6
|
|
|
7
|
-
console.log("
|
|
7
|
+
console.log("/")
|
|
8
8
|
|
|
9
9
|
const templatePath = path.join(__dirname, "templates")
|
|
10
10
|
const targetPath = path.join(process.cwd(), "my-app")
|
|
11
11
|
|
|
12
12
|
if (!fs.existsSync(templatePath)) {
|
|
13
|
-
console.log("
|
|
13
|
+
console.log("setup failed")
|
|
14
14
|
process.exit(1)
|
|
15
15
|
}
|
|
16
16
|
|
|
17
17
|
fs.copySync(templatePath, targetPath)
|
|
18
18
|
|
|
19
|
-
console.log("
|
|
19
|
+
console.log(".")
|
package/package.json
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
7
7
|
"test": "echo \"Error: no test specified\" && exit 1",
|
|
8
|
-
"dev": "concurrently \"nodemon
|
|
8
|
+
"dev": "concurrently \"nodemon server.js\" \"nodemon auth.js\""
|
|
9
9
|
},
|
|
10
10
|
"keywords": [],
|
|
11
11
|
"author": "",
|
|
@@ -8,7 +8,6 @@ const [email, setEmail] = useState('')
|
|
|
8
8
|
const [password, setPassword] = useState('')
|
|
9
9
|
const [error, setError] = useState('')
|
|
10
10
|
const [message, setMessage] = useState('')
|
|
11
|
-
const [loading, setLoading] = useState(false)
|
|
12
11
|
|
|
13
12
|
const navigate = useNavigate()
|
|
14
13
|
|
|
@@ -40,7 +39,6 @@ const handleLogin = async (e) => {
|
|
|
40
39
|
if (!validate()) return
|
|
41
40
|
|
|
42
41
|
try {
|
|
43
|
-
setLoading(true)
|
|
44
42
|
|
|
45
43
|
const res = await axios.post("http://localhost:3000/login", {
|
|
46
44
|
email,
|
|
@@ -63,8 +61,6 @@ const handleLogin = async (e) => {
|
|
|
63
61
|
} else {
|
|
64
62
|
setError("Server error. Try again")
|
|
65
63
|
}
|
|
66
|
-
} finally {
|
|
67
|
-
setLoading(false)
|
|
68
64
|
}
|
|
69
65
|
}
|
|
70
66
|
|
|
@@ -95,10 +91,117 @@ return (
|
|
|
95
91
|
/>
|
|
96
92
|
|
|
97
93
|
<button
|
|
98
|
-
disabled={loading}
|
|
99
94
|
className="w-full bg-blue-500 text-white p-2 rounded"
|
|
100
95
|
>
|
|
101
|
-
|
|
96
|
+
Login
|
|
97
|
+
</button>
|
|
98
|
+
|
|
99
|
+
<p className="mt-4 text-center text-sm">
|
|
100
|
+
don't have an account?
|
|
101
|
+
<Link to="/signup" className="text-blue-600 ml-2">signup</Link>
|
|
102
|
+
</p>
|
|
103
|
+
|
|
104
|
+
</form>
|
|
105
|
+
</div>
|
|
106
|
+
)
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
export default Loginimport { useState } from "react"
|
|
110
|
+
import axios from "axios"
|
|
111
|
+
import { Link, useNavigate } from "react-router-dom"
|
|
112
|
+
|
|
113
|
+
function Login() {
|
|
114
|
+
|
|
115
|
+
const [email, setEmail] = useState('')
|
|
116
|
+
const [password, setPassword] = useState('')
|
|
117
|
+
const [error, setError] = useState('')
|
|
118
|
+
const [message, setMessage] = useState('')
|
|
119
|
+
|
|
120
|
+
const navigate = useNavigate()
|
|
121
|
+
|
|
122
|
+
const validate = () => {
|
|
123
|
+
if (!email || !password) {
|
|
124
|
+
setError("All fields are required")
|
|
125
|
+
return false
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
if (!email.includes("@")) {
|
|
129
|
+
setError("Enter a valid email")
|
|
130
|
+
return false
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
if (password.length < 6) {
|
|
134
|
+
setError("Password must be at least 6 characters")
|
|
135
|
+
return false
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
return true
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
const handleLogin = async (e) => {
|
|
142
|
+
e.preventDefault()
|
|
143
|
+
|
|
144
|
+
setError('')
|
|
145
|
+
setMessage('')
|
|
146
|
+
|
|
147
|
+
if (!validate()) return
|
|
148
|
+
|
|
149
|
+
try {
|
|
150
|
+
|
|
151
|
+
const res = await axios.post("http://localhost:3000/login", {
|
|
152
|
+
email,
|
|
153
|
+
password
|
|
154
|
+
})
|
|
155
|
+
|
|
156
|
+
localStorage.setItem("token", res.data.token)
|
|
157
|
+
localStorage.setItem("user", JSON.stringify(res.data.user))
|
|
158
|
+
|
|
159
|
+
setMessage("Login successful")
|
|
160
|
+
setError("")
|
|
161
|
+
|
|
162
|
+
navigate("/admin")
|
|
163
|
+
|
|
164
|
+
} catch (err) {
|
|
165
|
+
if (err.response?.status === 404) {
|
|
166
|
+
setError("User not found")
|
|
167
|
+
} else if (err.response?.status === 401) {
|
|
168
|
+
setError("Wrong password")
|
|
169
|
+
} else {
|
|
170
|
+
setError("Server error. Try again")
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
return (
|
|
176
|
+
<div className="flex justify-center items-center h-screen bg-gray-100">
|
|
177
|
+
|
|
178
|
+
<form onSubmit={handleLogin} className="bg-white p-8 rounded-xl shadow-lg w-96">
|
|
179
|
+
|
|
180
|
+
<h1 className="text-3xl font-bold text-center mb-6">Login</h1>
|
|
181
|
+
|
|
182
|
+
{message && <p className="text-green-500 text-center mb-2">{message}</p>}
|
|
183
|
+
{error && <p className="text-red-500 text-center mb-2">{error}</p>}
|
|
184
|
+
|
|
185
|
+
<input
|
|
186
|
+
type="email"
|
|
187
|
+
value={email}
|
|
188
|
+
onChange={(e) => setEmail(e.target.value)}
|
|
189
|
+
placeholder="Email"
|
|
190
|
+
className="w-full border p-2 mb-3 rounded"
|
|
191
|
+
/>
|
|
192
|
+
|
|
193
|
+
<input
|
|
194
|
+
type="password"
|
|
195
|
+
value={password}
|
|
196
|
+
onChange={(e) => setPassword(e.target.value)}
|
|
197
|
+
placeholder="Password"
|
|
198
|
+
className="w-full border p-2 mb-3 rounded"
|
|
199
|
+
/>
|
|
200
|
+
|
|
201
|
+
<button
|
|
202
|
+
className="w-full bg-blue-500 text-white p-2 rounded"
|
|
203
|
+
>
|
|
204
|
+
Login
|
|
102
205
|
</button>
|
|
103
206
|
|
|
104
207
|
<p className="mt-4 text-center text-sm">
|
|
File without changes
|