Skip to content

Commit 2b2f125

Browse files
committed
Login modal
1 parent fc7b3aa commit 2b2f125

File tree

3 files changed

+134
-45
lines changed

3 files changed

+134
-45
lines changed

src/App.js

Lines changed: 31 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,11 @@ import AddCard from './Cards/AddCard'
66
import Context from './context'
77
import Loader from './Content/Loader'
88
import ModalCardEdit from './Modal/ModalCardEdit'
9+
import ModalLogin from './Modal/ModalLogin'
910
import Modal from './Modal/Modal'
1011
import DataService from './DataService'
1112

12-
const { loadData, postData, login } = DataService()
13+
const { loadData, postData, setLogin } = DataService()
1314

1415
const testText = "My little cards-app c:"
1516

@@ -59,18 +60,35 @@ function App() {
5960
const [editCardId, setEditCardId] = React.useState(null)
6061
const [loading, setLoading] = React.useState(true)
6162
const [logged, setLogged] = React.useState(false)
62-
React.useEffect(tryLogin, []) // eslint-disable-line react-hooks/exhaustive-deps
63+
const [userName, setUserName] = React.useState(null)
64+
React.useEffect(clearIfUnlogged, [logged]) // eslint-disable-line react-hooks/exhaustive-deps
6365
React.useEffect(loadDataFromServer, [logged]) // eslint-disable-line react-hooks/exhaustive-deps
6466
React.useEffect(loadDataToServer, [cardsArr]) // eslint-disable-line react-hooks/exhaustive-deps
6567

66-
6768
///////////
68-
function tryLogin() {
69-
try {
70-
login().then(setLogged, alert)
71-
} catch (e) {
72-
console.error(e)
73-
}
69+
function tryLogin(login) {
70+
return new Promise((res, rej) => {
71+
try {
72+
setLogin(login)
73+
.then((r => {
74+
setLogged(Boolean(r))
75+
setUserName(login)
76+
}), console.log)
77+
.then(res, rej)
78+
} catch (e) {
79+
rej(e)
80+
console.error(e)
81+
}
82+
})
83+
}
84+
85+
function dislogin() {
86+
if (logged) console.log("Dislogin")
87+
setLogged(null)
88+
}
89+
90+
function clearIfUnlogged() {
91+
if (logged === null && cardsArr) deleteAll()
7492
}
7593
///////////
7694

@@ -157,25 +175,25 @@ function App() {
157175
}
158176
///////////
159177

160-
161178
return (
162179
<Context.Provider value={{ removeCard, changeCardState, setEditCard, unsetEditCard, editCardContent, editCardId }}>
163180
<div className="App">
164181
<header className="p-1 h2 text-center">
165182
<img src={logo} className="App-logo" alt="logo" />
166183
<h1 className="d-inline-block h2">{testText}</h1>
167-
<p className="show_login" onClick={(e) => { e.target.style.opacity = e.target.style.opacity !== '0' ? '0' : '1' }}>
168-
{logged && `Login: ${logged}`}
184+
<p className="show_login btn btn-light py-0" onClick={(e) => { setLogged(logged === false ? 0 : false) }}>
185+
{logged ? `Login: ${userName}` : "LOG IN"}
169186
</p>
170187
</header>
171188

172189
<main className="p-1">
173190
<AddCard onCreate={addCard} onDeleteAll={deleteAll} />
191+
<Modal component={ModalLogin} componentProps={{ logged: logged, login: tryLogin, dislogin: dislogin, userName: userName }} />
174192
<Modal component={ModalCardEdit} componentProps={{ card: getCardByIndex(editCardId), index: editCardId }} />
175193
{loading && <Loader />}
176194
{cardsArr.length ? (
177195
<CardList cards={cardsArr} />
178-
) : loading ? null : (
196+
) : loading && !logged ? null : (
179197
<div className="container text-center">
180198
<p className="m-3 p-3 h5 text-muted">No cards. You can add a new one!</p>
181199
</div>

src/DataService.js

Lines changed: 6 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -7,37 +7,11 @@ export default function DataService() {
77
//let recuestCount = 1;
88

99
////////////////////////////////////////////////////////////
10-
function login() {
11-
return new Promise((submit, dismiss) => {
12-
function tryLogin(def) {
13-
let input = prompt(def ? "Исправьте логин" : "Введите логин", def || "")
14-
input === null
15-
? onDismiss()
16-
: checkLogin(input.trim())
17-
? onLogin(input.trim())
18-
: tryLogin(input.trim())
19-
}
20-
function onLogin(username) {
21-
user = username
22-
submit(username)
23-
console.log('Login:', user)
24-
}
25-
function onDismiss() {
26-
user = null
27-
dismiss("Вы не залогинились")
28-
console.log('Login dismissed')
29-
}
30-
$(() => tryLogin())
31-
})
32-
}
33-
34-
function checkLogin(str) {
35-
try {
36-
let filtered = str.replace(/@|;|:|\.|,|\/|\\|\||\$|\?|!|#|%|\*|\^|\+|=|\[|\]| |\\ |«|<|>/gi, "").trim()
37-
return (filtered && filtered.length > 3 && filtered.length < 20 && filtered === str)
38-
} catch {
39-
return false
40-
}
10+
function setLogin(login) {
11+
if (login && typeof login === "string") {
12+
user = login
13+
return Promise.resolve(user)
14+
} else return Promise.reject(login)
4115
}
4216
////////////////////////////////////////////////////////////
4317

@@ -132,5 +106,5 @@ export default function DataService() {
132106
}
133107
////////////////////////////////////////////////////////////
134108

135-
return { loadData, postData, login }
109+
return { loadData, postData, setLogin }
136110
}

src/Modal/ModalLogin.js

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
import React from 'react'
2+
import { ModalContext } from "./Modal"
3+
import PropTypes from 'prop-types'
4+
5+
function useInputValue(defaultValue) {
6+
const [value, setValue] = React.useState(defaultValue)
7+
8+
return {
9+
bind: {
10+
value,
11+
onChange: event => setValue(event.target.value)
12+
},
13+
clear: () => setValue(defaultValue),
14+
value: () => value
15+
}
16+
}
17+
18+
function checkLogin(str) {
19+
try {
20+
if (str === null) {
21+
return false
22+
}
23+
else {
24+
let filtered = str.replace(/@|;|:|\.|,|\/|\\|\||\$|\?|!|#|%|\*|\^|\+|=|\[|\]| |\\ |«|<|>/gi, "").trim()
25+
return (filtered && filtered.length > 3 && filtered.length < 20 && filtered === str)
26+
}
27+
} catch {
28+
return false
29+
}
30+
}
31+
32+
function ModalLogin(props) {
33+
const input = useInputValue(props.userName || "")
34+
const { open, close, isOpen } = React.useContext(ModalContext)
35+
const [msg, setMsg] = React.useState("Введите логин")
36+
React.useEffect(() => { if (!props.logged && props.logged !== null && !isOpen) open() }, [props.logged]) // eslint-disable-line react-hooks/exhaustive-deps
37+
38+
function onClose() {
39+
closeAndClear()
40+
onDismiss()
41+
}
42+
43+
function closeAndClear() {
44+
input.clear()
45+
close()
46+
}
47+
48+
function onLogin(username) {
49+
closeAndClear()
50+
console.log('Login:', username)
51+
}
52+
53+
function onDismiss() {
54+
props.dislogin()
55+
console.log('Login dismissed')
56+
}
57+
58+
function tryLogin(value) {
59+
return new Promise((res, rej) => {
60+
try {
61+
if (checkLogin(value.trim())) props.login(value.trim()).then(res, rej)
62+
else rej(value)
63+
} catch (e) {
64+
rej(e)
65+
console.error(e)
66+
}
67+
})
68+
}
69+
70+
function submitHandler() {
71+
if (String(input.value()).trim()) {
72+
tryLogin(String(input.value()).trim()).then(onLogin, () => setMsg("Исправьте логин"))
73+
} else setMsg("Введите логин")
74+
}
75+
76+
return (
77+
<React.Fragment>
78+
<div className='bg-light form-group'>
79+
<label htmlFor="login">{msg}</label>
80+
<input type="text" className="form-control" placeholder="Login" id="login" {...input.bind} />
81+
</div>
82+
<div className='bg-light form-group form-row'>
83+
<button className="btn btn-primary col m-1" onClick={submitHandler}>Log in</button>
84+
<button className="btn btn-danger col m-1" onClick={onClose}>Close</button>
85+
</div>
86+
</React.Fragment>
87+
)
88+
}
89+
90+
ModalLogin.propTypes = {
91+
logged: PropTypes.oneOfType([PropTypes.bool, PropTypes.number]),
92+
userName: PropTypes.oneOfType([PropTypes.bool, PropTypes.string]),
93+
login: PropTypes.func,
94+
dislogin: PropTypes.func
95+
}
96+
97+
export default ModalLogin

0 commit comments

Comments
 (0)