Skip to content

Commit ee24dcf

Browse files
committed
validation handling ux for join project secret
1 parent 4cdd974 commit ee24dcf

File tree

5 files changed

+47
-43
lines changed

5 files changed

+47
-43
lines changed

web/src/components/JoinProjectModal/JoinProjectModal.tsx

Lines changed: 36 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,13 @@ function JoinProjectForm({
1919
projectSecret,
2020
onSecretChange,
2121
invalidText,
22-
validatingSecret,
23-
onValidate,
22+
pendingJoiningProject,
23+
onClickDone,
2424
}) {
2525
const validateButtonContent = (
2626
<ButtonWithPendingState
27-
pending={validatingSecret}
28-
pendingText="Searching..."
27+
pending={pendingJoiningProject}
28+
pendingText="joining..."
2929
actionText="Join Project"
3030
/>
3131
)
@@ -51,7 +51,13 @@ function JoinProjectForm({
5151
/>
5252
</ProjectModalContent>
5353
</ProjectModalContentSpacer>
54-
<ProjectModalButton text={validateButtonContent} onClick={onValidate} />
54+
<ProjectModalButton
55+
text={validateButtonContent}
56+
onClick={onClickDone}
57+
// show the button as disabled if there is a text about invalid secret input
58+
// or if there is no input
59+
disabled={invalidText !== '' || projectSecret === ''}
60+
/>
5561
</div>
5662
)
5763
}
@@ -74,7 +80,11 @@ function ProjectJoinFollowUp({ onDone, checkDone }) {
7480
required before you can access it.
7581
</div>
7682
</ProjectModalContent>
77-
<ProjectModalButton text="I understand" onClick={onDone} />
83+
<ProjectModalButton
84+
text="I understand"
85+
onClick={onDone}
86+
disabled={false}
87+
/>
7888
</div>
7989
)
8090
}
@@ -87,26 +97,22 @@ export default function JoinProjectModal({
8797
}) {
8898
const reset = () => {
8999
setProjectSecret('')
90-
setValidatingSecret(false)
100+
setPendingJoiningProject(false)
91101
setInvalidText('')
92102
setCheckDone(false)
93103
}
94-
const onValidate = async () => {
95-
// check if the sectrest is five words or not
96-
if (invalidText || projectSecret.length === 0) {
97-
setInvalidText('Secret must be 5 words.')
98-
return
99-
}
100-
// Check if the secret is already joined
101-
if (joinedProjectsSecrets.includes(projectSecret)) {
102-
setInvalidText("You've already joined this project!")
103-
return
104-
}
105-
setValidatingSecret(true)
104+
105+
const [checkDone, setCheckDone] = useState(false)
106+
const [projectSecret, setProjectSecret] = useState('')
107+
const [invalidText, setInvalidText] = useState('')
108+
const [pendingJoiningProject, setPendingJoiningProject] = useState(false)
109+
110+
const onClickDone = async () => {
111+
setPendingJoiningProject(true)
106112
try {
107113
await onJoinProject(projectSecret)
108114
setCheckDone(true)
109-
setValidatingSecret(false)
115+
setPendingJoiningProject(false)
110116
} catch (e) {
111117
console.log(e)
112118
// TODO: add better detail here
@@ -118,21 +124,17 @@ export default function JoinProjectModal({
118124
onClose()
119125
}
120126

121-
const [checkDone, setCheckDone] = useState(false)
122-
const [projectSecret, setProjectSecret] = useState('')
123-
const [invalidText, setInvalidText] = useState('')
124-
125-
const [validatingSecret, setValidatingSecret] = useState(false)
126-
127-
const onSecretChange = (val) => {
127+
const onSecretChange = (userInputText: string) => {
128128
setInvalidText('')
129-
setValidatingSecret(false)
130-
setProjectSecret(val)
131-
if (!val) {
129+
setPendingJoiningProject(false)
130+
setProjectSecret(userInputText)
131+
if (!userInputText) {
132132
setInvalidText('')
133+
} else if (joinedProjectsSecrets.includes(userInputText)) {
134+
setInvalidText("You've already joined this project!")
133135
} else if (
134-
val.split(' ').length !== 5 ||
135-
!val.split(' ').every((word) => word.length)
136+
userInputText.split(' ').length !== 5 ||
137+
!userInputText.split(' ').every((word) => word.length)
136138
) {
137139
setInvalidText('Secret must be 5 words.')
138140
}
@@ -151,8 +153,8 @@ export default function JoinProjectModal({
151153
projectSecret={projectSecret}
152154
onSecretChange={onSecretChange}
153155
invalidText={invalidText}
154-
validatingSecret={validatingSecret}
155-
onValidate={onValidate}
156+
pendingJoiningProject={pendingJoiningProject}
157+
onClickDone={onClickDone}
156158
/>
157159
</Modal>
158160
)

web/src/components/ProjectModal/ProjectModal.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,10 @@ function ProjectModalContent({ children }) {
2424
return <div className="project-modal-content">{children}</div>
2525
}
2626

27-
function ProjectModalButton({ text, onClick }) {
27+
function ProjectModalButton({ text, onClick, disabled }) {
2828
return (
2929
<div className="project-modal-button">
30-
<Button text={text} onClick={onClick} />
30+
<Button text={text} onClick={onClick} disabled={disabled} />
3131
</div>
3232
)
3333
}

web/src/components/ProjectSecret/ProjectSecret.js

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ export default function ProjectSecret({ passphrase }) {
2323
label="Project Invitation Secret"
2424
helpText="Share this secret phrase with people you want to invite to this project."
2525
/>
26+
{/* copy to clipboard button */}
2627
<div
2728
onClick={copySecretToClipboard}
2829
className="project-secret-copy-secret"
@@ -34,10 +35,10 @@ export default function ProjectSecret({ passphrase }) {
3435
name="file-copy.svg"
3536
/>
3637
</div>
38+
{showCopyMessage && (
39+
<div className="secret-copy-message">{copyMessage}</div>
40+
)}
3741
</div>
38-
{showCopyMessage && (
39-
<div className="secret-copy-message">{copyMessage}</div>
40-
)}
4142
</div>
4243
)
4344
}

web/src/components/ProjectSecret/ProjectSecret.scss

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
display: flex;
99
flex-direction: row;
1010
align-items: flex-end;
11+
position: relative;
1112
}
1213

1314
.project-secret-row .validating-form-input {
@@ -41,9 +42,9 @@
4142
}
4243

4344
.secret-copy-message {
44-
position: absolute;
45-
top: 118px;
4645
color: #00a599;
47-
margin-left: 10px;
4846
font-size: 14px;
47+
position: absolute;
48+
bottom: -1.375rem;
49+
left: 0.25rem;
4950
}

web/src/components/ValidatingFormInput/ValidatingFormInput.scss

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@
7575
color: #ff5d36;
7676
font-size: 0.75rem;
7777
position: absolute;
78-
top: 3.125rem;
78+
top: 3.25rem;
7979
left: 0.25rem;
8080
}
8181

0 commit comments

Comments
 (0)