Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
M
mr-julyedu
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
baiguangyao
mr-julyedu
Commits
b41c453e
Commit
b41c453e
authored
Sep 17, 2019
by
zhanghaozhe
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
忘记密码
parent
983b183b
Hide whitespace changes
Inline
Side-by-side
Showing
16 changed files
with
330 additions
and
75 deletions
+330
-75
src/components/country/countryRedux.js
+1
-1
src/components/country/index.js
+2
-1
src/components/passport/common/LoginWays/index.js
+6
-10
src/components/passport/common/clearableInputWithCountryCodes/index.js
+25
-0
src/components/passport/common/clearableInputWithCountryCodes/index.scss
+35
-0
src/components/passport/common/inputWithCountryCodes/index.js
+8
-2
src/components/passport/common/inputWithCountryCodes/index.scss
+22
-5
src/components/passport/common/veriCodeInput/index.js
+15
-14
src/components/passport/forgotPassword/forgot-password.scss
+9
-4
src/components/passport/forgotPassword/index.js
+22
-30
src/components/passport/forgotPasswordEmail/index.js
+140
-0
src/components/passport/forgotPasswordEmail/index.scss
+38
-0
src/components/passport/index.js
+3
-0
src/components/passport/login/index.js
+2
-2
src/components/passport/login/wechatLogin.scss
+2
-2
src/components/passport/setPassword/index.js
+0
-4
No files found.
src/components/country/countryRedux.js
View file @
b41c453e
...
...
@@ -10,7 +10,7 @@ export const delCountryNum = () => ({
type
:
'DEL_COUNTRY_NUM'
});
export
default
(
state
=
{},
action
)
=>
{
export
default
(
state
=
{
num
:
86
,
code
:
null
},
action
)
=>
{
const
{
type
,
payload
}
=
action
;
switch
(
type
)
{
case
ADD_COUNTRY_NUM
:
...
...
src/components/country/index.js
View file @
b41c453e
...
...
@@ -53,7 +53,8 @@ class Country extends Component {
num
,
code
:
getParam
(
'share_code'
)
});
history
.
push
(
`/detail?id=
${
getParam
(
'id'
)}
`
);
// history.push(`/detail?id=${getParam('id')}`);
history
.
go
(
-
1
)
e
.
preventDefault
();
}
...
...
src/components/passport/common/LoginWays/index.js
View file @
b41c453e
...
...
@@ -6,13 +6,8 @@ import more from '../../icons/more.png'
class
LoginWays
extends
PureComponent
{
state
=
{
ways
:
browser
.
isWeixin
?
this
.
props
.
loginWays
.
slice
(
0
,
2
)
:
this
.
props
.
loginWays
.
slice
(
0
,
1
)
}
componentDidMount
()
{
this
.
setState
({
ways
:
this
.
filterWays
()
})
ways
:
browser
.
isWeixin
?
this
.
props
.
loginWays
.
slice
(
0
,
2
)
:
this
.
props
.
loginWays
.
slice
(
0
,
1
),
showMore
:
true
}
...
...
@@ -21,12 +16,13 @@ class LoginWays extends PureComponent {
}
filterWays
=
()
=>
{
return
browser
.
isWeixin
?
this
.
props
.
loginWays
:
this
.
state
.
w
ays
.
filter
(
item
=>
item
.
id
!==
'wechat'
)
return
browser
.
isWeixin
?
this
.
props
.
loginWays
:
this
.
props
.
loginW
ays
.
filter
(
item
=>
item
.
id
!==
'wechat'
)
}
showMore
=
()
=>
{
this
.
setState
({
ways
:
this
.
props
.
loginWays
ways
:
this
.
filterWays
(),
showMore
:
false
})
}
...
...
@@ -46,7 +42,7 @@ class LoginWays extends PureComponent {
})
}
{
this
.
state
.
ways
.
length
!==
this
.
props
.
loginWays
.
length
&&
this
.
state
.
showMore
&&
<
li
className
=
{
'more'
}
onClick
=
{
this
.
showMore
}
>
<
img
src
=
{
more
}
alt
=
"更多"
/>
<
p
>
更多
<
/p
>
...
...
src/components/passport/common/clearableInputWithCountryCodes/index.js
0 → 100644
View file @
b41c453e
import
React
,
{
Component
}
from
'react'
;
import
ClearableInput
from
'@common/ClearableInput'
import
'./index.scss'
import
{
Link
}
from
"react-router-dom"
;
class
ClearableInputWithCountryCodes
extends
Component
{
render
()
{
const
{
country
,
...
rest
}
=
this
.
props
return
(
<
div
className
=
{
'clearable-input-with-country-codes'
}
>
<
div
className
=
"country-code"
>
<
Link
to
=
{
'/country'
}
>
+
{
country
&&
country
.
num
||
86
}
<
i
className
=
{
'iconfont iconiconfront-69'
}
/
>
<
/Link
>
<
/div
>
<
ClearableInput
{...
rest
}
/
>
<
/div
>
);
}
}
export
default
ClearableInputWithCountryCodes
;
\ No newline at end of file
src/components/passport/common/clearableInputWithCountryCodes/index.scss
0 → 100644
View file @
b41c453e
.clearable-input-with-country-codes
{
display
:
flex
;
border
:
1px
solid
#ccc
;
border-radius
:
3px
;
margin-bottom
:
24px
;
.clearable-input-wrapper
{
margin-bottom
:
0
;
flex
:
1
1
auto
;
input
{
padding-left
:
10px
;
border
:
none
;
width
:
100%
;
padding-right
:
34px
;
}
}
.country-code
{
flex-shrink
:
0
;
display
:
flex
;
justify-content
:
center
;
align-items
:
center
;
font-size
:
15px
;
color
:
#333
;
width
:
63px
;
text-align
:
center
;
border-right
:
1px
solid
#ccc
;
.iconfont
{
margin-left
:
3px
;
}
}
}
\ No newline at end of file
src/components/passport/common/inputWithCountryCodes/index.js
View file @
b41c453e
...
...
@@ -3,13 +3,19 @@ import './index.scss'
import
Input
from
'../Input'
class
InputWithCountryCodes
extends
Component
{
static
defaultProps
=
{
countryCode
:
'86'
}
render
()
{
const
{
countryCode
,
...
rest
}
=
this
.
props
return
(
<
div
className
=
{
'input-with-country-codes'
}
>
<
div
className
=
"country-codes"
>
<
i
className
=
{
'iconfont iconiconfront-69'
}
><
/i
>
+
{
countryCode
}
<
i
className
=
{
'iconfont iconiconfront-69'
}
/
>
<
/div
>
<
Input
/>
<
Input
{...
rest
}
/
>
<
/div
>
);
}
...
...
src/components/passport/common/inputWithCountryCodes/index.scss
View file @
b41c453e
.input-with-country-codes
{
.input-wrapper
{
.input
{
.input-with-country-codes
{
display
:
flex
;
border
:
1px
solid
#ccc
;
border-radius
:
3px
;
margin-bottom
:
24px
;
.tel-input
{
margin-bottom
:
0
;
.input
{
padding-left
:
10px
;
border
:
none
;
}
}
.country-codes
{
font-size
:
10px
;
.country-codes
{
flex-shrink
:
0
;
display
:
flex
;
justify-content
:
center
;
align-items
:
center
;
font-size
:
15px
;
color
:
#333
;
width
:
63px
;
text-align
:
center
;
border-right
:
1px
solid
#ccc
;
}
}
\ No newline at end of file
src/components/passport/common/veriCodeInput/index.js
View file @
b41c453e
import
React
,
{
Component
}
from
'react'
;
import
'./veri-code-input.scss'
import
{
http
,
validateEmail
,
validateTel
}
from
'@/utils'
;
import
{
http
,
validateEmail
}
from
'@/utils'
;
import
{
Toast
}
from
"antd-mobile"
;
import
{
has
}
from
'lodash'
...
...
@@ -47,8 +47,8 @@ class VeriCodeInput extends Component {
}
getType
=
()
=>
{
const
{
account
}
=
this
.
props
if
(
validateEmail
(
account
))
{
const
{
email
}
=
this
.
props
if
(
validateEmail
(
email
))
{
return
'email'
}
}
...
...
@@ -61,9 +61,9 @@ class VeriCodeInput extends Component {
}
sendEmail
=
()
=>
{
const
{
account
,
challenge
}
=
this
.
props
const
{
email
,
challenge
}
=
this
.
props
http
.
post
(
`
${
API
[
'passport-api'
]}
/send_email_code`
,
{
email
:
account
,
email
,
challenge
}).
then
(
res
=>
{
if
(
res
.
data
.
errno
===
0
)
{
...
...
@@ -79,14 +79,15 @@ class VeriCodeInput extends Component {
}
sendSMS
=
()
=>
{
const
{
action
,
tel
,
account
,
challenge
,
checking
}
=
this
.
props
if
(
!
tel
&&
!
account
)
{
Toast
.
info
(
'请输入手机号
或邮箱地址
'
)
const
{
action
,
tel
,
account
,
challenge
,
checking
,
country
}
=
this
.
props
if
(
!
tel
)
{
Toast
.
info
(
'请输入手机号'
)
return
}
http
.
post
(
`
${
API
[
'passport-api'
]}
/quick_sms`
,
{
phone_num
:
tel
||
account
,
action
:
action
||
'login'
,
area_code
:
country
.
num
,
challenge
,
checking
}).
then
(
res
=>
{
...
...
@@ -103,7 +104,7 @@ class VeriCodeInput extends Component {
validate
=
()
=>
{
const
{
tel
,
challenge
,
account
}
=
this
.
props
const
{
tel
,
challenge
,
email
}
=
this
.
props
let
hasTel
=
has
(
this
.
props
,
'tel'
)
let
content
...
...
@@ -111,15 +112,15 @@ class VeriCodeInput extends Component {
if
(
!
tel
)
{
content
=
'手机号码不能为空'
}
if
(
!
validateTel
(
tel
))
{
if
(
!
/
\d
/
.
test
(
tel
))
{
content
=
'请输入正确格式的手机号码'
}
}
else
{
if
(
!
account
)
{
content
=
'
手机号或
电子邮件不能为空'
if
(
!
email
)
{
content
=
'电子邮件不能为空'
}
if
(
!
validate
Tel
(
account
)
&&
!
validateEmail
(
account
))
{
content
=
'请输入正确格式的
手机号或
电子邮件'
if
(
!
validate
Email
(
email
))
{
content
=
'请输入正确格式的电子邮件'
}
}
...
...
src/components/passport/forgotPassword/forgot-password.scss
View file @
b41c453e
...
...
@@ -4,6 +4,13 @@
.content
{
padding
:
38px
36px
;
text-align
:
center
;
.to-email
{
line-height
:
55px
;
font-size
:
15px
;
color
:
#666
;
}
}
...
...
@@ -14,10 +21,6 @@
background
:
#56abff
;
}
.tel-input
{
margin-bottom
:
21px
;
}
.verify-code
{
margin-bottom
:
21px
;
}
...
...
@@ -25,4 +28,5 @@
.next_step
{
margin-top
:
32px
;
}
}
\ No newline at end of file
src/components/passport/forgotPassword/index.js
View file @
b41c453e
...
...
@@ -6,10 +6,12 @@ import { withFormik, Form, Field } from 'formik';
import
{
connect
}
from
'react-redux'
;
import
{
compose
}
from
'redux'
;
import
{
Toast
}
from
"antd-mobile"
;
import
{
HeaderBar
,
Captcha
,
ClearableInput
}
from
"@/common"
;
import
{
validateTel
,
validateEmail
,
http
,
api
}
from
"@/utils"
;
import
{
HeaderBar
,
Captcha
}
from
"@/common"
;
import
ClearableInput
from
'../common/clearableInputWithCountryCodes'
import
{
validateTel
,
http
,
api
}
from
"@/utils"
;
import
{
quickLogin
}
from
'@/store/userAction'
;
import
OnSubmissionError
from
'../common/OnSubmissionError'
import
{
Link
}
from
"react-router-dom"
;
class
ForgotPassword
extends
Component
{
...
...
@@ -42,7 +44,8 @@ class ForgotPassword extends Component {
render
()
{
const
{
values
,
isValid
isValid
,
country
}
=
this
.
props
return
(
<
div
className
=
{
'forgot-password'
}
>
...
...
@@ -50,18 +53,16 @@ class ForgotPassword extends Component {
<
div
className
=
"content"
>
<
Form
className
=
'forgot-password-form'
>
<
Field
name
=
{
'
account
'
}
name
=
{
'
tel
'
}
render
=
{({
field
,
form
})
=>
{
return
(
<
ClearableInput
{...
field
}
type
=
{
'tel'
}
placeholder
=
{
'请输入注册时的
邮箱账号或
手机号'
}
placeholder
=
{
'请输入注册时的手机号'
}
wrapperClass
=
{
'tel-input'
}
setFieldValue
=
{
form
.
setFieldValue
}
icon
=
{
<
i
className
=
{
'iconfont iconshouji'
}
style
=
{{
fontSize
:
'22px'
,
left
:
'11px'
}}
/>
}
country
=
{
country
}
/>
)
}}
/
>
...
...
@@ -77,11 +78,12 @@ class ForgotPassword extends Component {
icon
=
{
<
i
className
=
{
'iconfont iconduanxin'
}
style
=
{{
fontSize
:
'20px'
,
left
:
'12px'
}}
/>
}
account
=
{
values
.
account
}
tel
=
{
values
.
tel
}
challenge
=
{
this
.
state
.
validate
}
instance
=
{
this
.
state
.
captchaInstance
}
action
=
{
'auth'
}
checking
=
{
1
}
country
=
{
country
}
/
>
)
}}
...
...
@@ -90,6 +92,7 @@ class ForgotPassword extends Component {
<
OnSubmissionError
callback
=
{
this
.
onSubmissionError
}
/
>
<
Captcha
getInstance
=
{
this
.
getCaptchaInstance
}
onVerify
=
{
this
.
onVerify
}
/
>
<
Button
className
=
{
'next_step'
}
active
=
{
isValid
}
>
下一步
<
/Button
>
<
Link
className
=
{
'to-email'
}
to
=
{
`/passport/forgot-password-email`
}
replace
>
邮箱找回
<
/Link
>
<
/Form
>
<
/div
>
<
/div
>
...
...
@@ -101,37 +104,26 @@ class ForgotPassword extends Component {
const
formikConfig
=
{
mapPropsToValues
:
()
=>
({
account
:
''
,
tel
:
''
,
veriCode
:
''
}),
validateOnChange
:
true
,
validateOnBlur
:
true
,
validate
:
values
=>
{
let
errors
=
{}
if
(
!
validateTel
(
values
.
account
)
&&
!
validateEmail
(
values
.
account
))
{
errors
.
account
=
'请输入正确的手机号或邮箱地址
'
if
(
!
validateTel
(
values
.
tel
))
{
errors
.
tel
=
'请输入正确的手机号
'
}
values
.
veriCode
.
toString
().
length
!==
6
&&
(
errors
.
veriCode
=
'验证码格式不正确'
)
return
errors
},
handleSubmit
(
values
,
{
props
})
{
let
account
,
address
if
(
validateEmail
(
values
.
account
))
{
account
=
'email'
address
=
'check_email_code'
sessionStorage
.
setItem
(
'r_type'
,
'email'
)
sessionStorage
.
setItem
(
'email'
,
values
.
account
)
}
else
{
account
=
'phone'
address
=
'check_phone_code'
sessionStorage
.
setItem
(
'r_type'
,
'phone'
)
sessionStorage
.
setItem
(
'tel'
,
values
.
account
)
}
http
.
post
(
`
${
API
[
'passport-api'
]}
/
${
address
}
`
,
{
[
account
]:
values
.
account
,
code
:
values
.
veriCode
sessionStorage
.
setItem
(
'r_type'
,
'phone'
)
sessionStorage
.
setItem
(
'tel'
,
values
.
tel
)
http
.
post
(
`
${
API
[
'passport-api'
]}
/check_phone_code`
,
{
phone
:
values
.
tel
,
code
:
values
.
veriCode
,
area_code
:
props
.
country
.
num
}).
then
(
res
=>
{
if
(
res
.
data
.
errno
==
0
)
{
props
.
history
.
push
(
'/passport/set-password'
,
{
from
:
props
.
location
})
...
...
@@ -145,7 +137,7 @@ const formikConfig = {
export
default
compose
(
connect
(
null
,
state
=>
({
country
:
state
.
country
})
,
{
quickLogin
}
),
withFormik
(
formikConfig
)
...
...
src/components/passport/forgotPasswordEmail/index.js
0 → 100644
View file @
b41c453e
import
React
,
{
Component
}
from
'react'
import
'./index.scss'
import
VeriCodeInput
from
'../common/veriCodeInput'
import
Button
from
'../common/Button'
import
{
withFormik
,
Form
,
Field
}
from
'formik'
;
import
{
connect
}
from
'react-redux'
;
import
{
compose
}
from
'redux'
;
import
{
Toast
}
from
"antd-mobile"
;
import
{
HeaderBar
,
Captcha
,
ClearableInput
}
from
"@/common"
;
import
{
validateEmail
,
http
,
api
}
from
"@/utils"
;
import
{
quickLogin
}
from
'@/store/userAction'
;
import
OnSubmissionError
from
'../common/OnSubmissionError'
import
{
Link
}
from
"react-router-dom"
;
class
ForgotPassword
extends
Component
{
state
=
{
validate
:
null
,
captchaInstance
:
null
}
getCaptchaInstance
=
instance
=>
{
this
.
setState
({
captchaInstance
:
instance
})
}
onVerify
=
(
err
,
data
)
=>
{
if
(
err
)
{
console
.
log
(
err
)
}
else
{
this
.
setState
({
validate
:
data
.
validate
})
}
}
onSubmissionError
=
()
=>
{
const
errors
=
Object
.
values
(
this
.
props
.
errors
);
errors
.
length
&&
Toast
.
info
(
errors
[
0
],
2
,
null
,
false
)
}
render
()
{
const
{
values
,
isValid
}
=
this
.
props
return
(
<
div
className
=
{
'forgot-password-email'
}
>
<
HeaderBar
title
=
'忘记密码'
arrow
=
{
true
}
/
>
<
div
className
=
"content"
>
<
Form
className
=
'forgot-password-form'
>
<
Field
name
=
{
'email'
}
render
=
{({
field
,
form
})
=>
{
return
(
<
ClearableInput
{...
field
}
type
=
{
'email'
}
placeholder
=
{
'请输入注册时的邮箱账号'
}
wrapperClass
=
{
'email-input'
}
setFieldValue
=
{
form
.
setFieldValue
}
/>
)
}}
/
>
{
this
.
state
.
validate
&&
<
Field
name
=
'veriCode'
render
=
{({
field
})
=>
{
return
(
<
VeriCodeInput
{...
field
}
className
=
{
'verify-code'
}
icon
=
{
<
i
className
=
{
'iconfont iconduanxin'
}
style
=
{{
fontSize
:
'20px'
,
left
:
'12px'
}}
/>
}
email
=
{
values
.
email
}
challenge
=
{
this
.
state
.
validate
}
instance
=
{
this
.
state
.
captchaInstance
}
action
=
{
'auth'
}
checking
=
{
1
}
/
>
)
}}
/
>
}
<
OnSubmissionError
callback
=
{
this
.
onSubmissionError
}
/
>
<
Captcha
getInstance
=
{
this
.
getCaptchaInstance
}
onVerify
=
{
this
.
onVerify
}
/
>
<
Button
className
=
{
'next_step'
}
active
=
{
isValid
}
>
下一步
<
/Button
>
<
Link
className
=
{
'to-phone'
}
to
=
{
'/passport/forgot-password'
}
replace
>
手机号找回
<
/Link
>
<
/Form
>
<
/div
>
<
/div
>
);
}
}
const
formikConfig
=
{
mapPropsToValues
:
()
=>
({
email
:
''
,
veriCode
:
''
}),
validateOnChange
:
true
,
validateOnBlur
:
true
,
validate
:
values
=>
{
let
errors
=
{}
if
(
!
validateEmail
(
values
.
email
))
{
errors
.
email
=
'请输入正确的邮箱地址'
}
values
.
veriCode
.
toString
().
length
!==
6
&&
(
errors
.
veriCode
=
'验证码格式不正确'
)
return
errors
},
handleSubmit
(
values
,
{
props
})
{
sessionStorage
.
setItem
(
'r_type'
,
'email'
)
sessionStorage
.
setItem
(
'email'
,
values
.
email
)
http
.
post
(
`
${
API
[
'passport-api'
]}
/check_email_code`
,
{
email
:
values
.
email
,
code
:
values
.
veriCode
}).
then
(
res
=>
{
if
(
res
.
data
.
errno
==
0
)
{
props
.
history
.
push
(
'/passport/set-password'
,
{
from
:
props
.
location
})
}
else
{
Toast
.
info
(
res
.
data
.
msg
,
2
,
null
,
false
)
}
})
},
}
export
default
compose
(
connect
(
null
,
{
quickLogin
}
),
withFormik
(
formikConfig
)
)(
ForgotPassword
)
\ No newline at end of file
src/components/passport/forgotPasswordEmail/index.scss
0 → 100644
View file @
b41c453e
.forgot-password-email
{
height
:
100%
;
.content
{
padding
:
38px
36px
;
text-align
:
center
;
.to-phone
{
line-height
:
55px
;
font-size
:
15px
;
color
:
#666
;
}
.email-input
{
margin-bottom
:
21px
;
input
{
padding-left
:
10px
;
}
}
}
.place
{
width
:
100%
;
height
:
39px
;
margin-bottom
:
33px
;
background
:
#56abff
;
}
.verify-code
{
margin-bottom
:
21px
;
}
.next_step
{
margin-top
:
32px
;
}
}
\ No newline at end of file
src/components/passport/index.js
View file @
b41c453e
...
...
@@ -8,8 +8,10 @@ import AccountLogin from './accountLogin'
import
ForgotPassword
from
'./forgotPassword'
import
SetPassword
from
'./setPassword'
import
BindingTel
from
'./bindingTel'
import
ForgotPasswordEmail
from
'./forgotPasswordEmail'
import
{
connect
}
from
"react-redux"
;
import
{
compose
}
from
"redux"
;
import
{
getParam
}
from
"@/utils"
;
import
account
from
'./icons/account.png'
import
qq
from
'./icons/qq.png'
...
...
@@ -96,6 +98,7 @@ class Passport extends Component {
}}
/
>
<
Route
path
=
{
match
.
url
+
'/account-login'
}
component
=
{
AccountLogin
}
/
>
<
Route
path
=
{
match
.
url
+
'/forgot-password'
}
component
=
{
ForgotPassword
}
/
>
<
Route
path
=
{
match
.
url
+
'/forgot-password-email'
}
component
=
{
ForgotPasswordEmail
}
/
>
<
Route
path
=
{
match
.
url
+
'/set-password'
}
component
=
{
SetPassword
}
/
>
<
Route
path
=
{
match
.
url
+
'/binding-tel'
}
component
=
{
BindingTel
}
/
>
<
/Switch
>
...
...
src/components/passport/login/index.js
View file @
b41c453e
...
...
@@ -85,9 +85,9 @@ class Login extends Component {
type
=
{
'tel'
}
placeholder
=
{
'手机号快捷登录(免注册)'
}
wrapperClass
=
{
'tel-input'
}
icon
=
{
<
i
className
=
{
'iconfont iconshouji'
}
/*
icon={<i className={'iconfont iconshouji'}
style={{fontSize: '22px', left: '10px'}}
/>
}
/>}
*/
/
>
)}
>
...
...
src/components/passport/login/wechatLogin.scss
View file @
b41c453e
...
...
@@ -8,9 +8,9 @@
padding
:
0
38px
;
flex
:
1
0
auto
;
.tel-input
{
/*
.tel-input {
margin-bottom: 24px;
}
}
*/
.verification
{
margin-bottom
:
24px
;
...
...
src/components/passport/setPassword/index.js
View file @
b41c453e
...
...
@@ -16,10 +16,6 @@ import { connect } from "react-redux";
class
SetPassword
extends
Component
{
componentDidMount
()
{
// console.log(this.props.location);
}
render
()
{
let
{
values
,
errors
,
location
}
=
this
.
props
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment