Skip to content

Commit

Permalink
Improve UI for code input (#198)
Browse files Browse the repository at this point in the history
  • Loading branch information
byn9826 authored Dec 7, 2024
1 parent 51d7a7e commit 5233a93
Show file tree
Hide file tree
Showing 10 changed files with 142 additions and 9 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "melody-auth",
"version": "1.1.1",
"version": "1.1.2",
"description": "A turnkey OAuth & authentication system.",
"license": "MIT",
"author": "Baozier",
Expand Down
4 changes: 4 additions & 0 deletions server/src/configs/locale.ts
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,10 @@ export const authorizeEmailMfa = Object.freeze({
en: 'Verify',
fr: 'Vérifier',
},
code: {
en: 'Enter your verification code here',
fr: 'Entrez votre code de vérification ici',
},
resend: {
en: 'Resend a new code',
fr: 'Renvoyer un nouveau code',
Expand Down
5 changes: 3 additions & 2 deletions server/src/views/AuthorizeEmailMfa.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ import {
resetErrorScript,
} from 'views/scripts'
import SubmitError from 'views/components/SubmitError'
import Field from 'views/components/Field'
import SubmitButton from 'views/components/SubmitButton'
import CodeInput from 'views/components/CodeInput'

const AuthorizeEmailMfa = ({
queryDto, logoUrl, locales, error,
Expand Down Expand Up @@ -40,10 +40,11 @@ const AuthorizeEmailMfa = ({
onsubmit='return handleSubmit(event)'
>
<section class='flex-col gap-4'>
<Field
<CodeInput
type='text'
required={false}
name='code'
label={localeConfig.authorizeEmailMfa.code[queryDto.locale]}
/>
<button
id='resend-btn'
Expand Down
3 changes: 2 additions & 1 deletion server/src/views/AuthorizeReset.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import Title from 'views/components/Title'
import Field from 'views/components/Field'
import { oauthDto } from 'dtos'
import SubmitButton from 'views/components/SubmitButton'
import CodeInput from 'views/components/CodeInput'

const AuthorizeReset = ({
logoUrl, queryString, queryDto, locales,
Expand Down Expand Up @@ -57,7 +58,7 @@ const AuthorizeReset = ({
required
name='email'
/>
<Field
<CodeInput
label={localeConfig.authorizeReset.code[queryDto.locale]}
type='text'
required
Expand Down
3 changes: 2 additions & 1 deletion server/src/views/AuthorizeSmsMfa.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
import SubmitError from 'views/components/SubmitError'
import Field from 'views/components/Field'
import SubmitButton from 'views/components/SubmitButton'
import CodeInput from 'views/components/CodeInput'

const AuthorizeSmsMfa = ({
queryDto, logoUrl, locales, phoneNumber, showEmailMfaBtn,
Expand Down Expand Up @@ -51,7 +52,7 @@ const AuthorizeSmsMfa = ({
>
{localeConfig.authorizeSmsMfa.resend[queryDto.locale]}
</button>
<Field
<CodeInput
label={localeConfig.authorizeSmsMfa.code[queryDto.locale]}
type='text'
required={false}
Expand Down
3 changes: 2 additions & 1 deletion server/src/views/ChangeEmail.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import Title from 'views/components/Title'
import Field from 'views/components/Field'
import { identityDto } from 'dtos'
import SubmitButton from 'views/components/SubmitButton'
import CodeInput from 'views/components/CodeInput'

const ChangeEmail = ({
logoUrl, queryDto, locales, redirectUri,
Expand Down Expand Up @@ -56,7 +57,7 @@ const ChangeEmail = ({
required
name='email'
/>
<Field
<CodeInput
label={localeConfig.changeEmail.code[queryDto.locale]}
type='text'
required
Expand Down
4 changes: 2 additions & 2 deletions server/src/views/VerifyEmail.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ import {
resetErrorScript, responseScript, validateScript,
} from 'views/scripts'
import Title from 'views/components/Title'
import Field from 'views/components/Field'
import SubmitError from 'views/components/SubmitError'
import CodeInput from 'views/components/CodeInput'

const VerifyEmail = ({
queryDto, logoUrl, locales,
Expand Down Expand Up @@ -44,7 +44,7 @@ const VerifyEmail = ({
onsubmit='return handleSubmit(event)'
>
<section class='flex-col gap-2'>
<Field
<CodeInput
type='text'
required={false}
name='code'
Expand Down
117 changes: 117 additions & 0 deletions server/src/views/components/CodeInput.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
import { html } from 'hono/html'
import { resetSubmitError } from 'views/scripts/resetError'

const CodeInput = ({
label,
required,
type,
name,
className,
value,
}: {
label?: string;
required: boolean;
type: 'email' | 'text' | 'password';
name: string;
className?: string;
value?: string;
}) => {
return (
<section
id={`${name}-row`}
class={`flex-col gap-2 ${className || ''}`}
>
<label
class='label w-text'
for={`form-${name}`}
>
{label}
{required && <span class='text-red ml-2'>*</span>}
</label>
<section class='flex-row gap-2'>
<input
class='code-input'
type='text'
id='code-input-1'
/>
<input
class='code-input'
type='text'
id='code-input-2'
/>
<input
class='code-input'
type='text'
id='code-input-3'
/>
<input
class='code-input'
type='text'
id='code-input-4'
/>
<input
class='code-input'
type='text'
id='code-input-5'
/>
<input
class='code-input'
type='text'
id='code-input-6'
/>
</section>
<input
class='input hidden'
type={type}
name={name}
id={`form-${name}`}
value={value}
/>
<p
id={`error-${name}`}
class='text-red hidden text-sm w-text'>
</p>
{html`
<script>
var codeInputs = document.querySelectorAll(".code-input");
var hiddenInput = document.getElementById("form-${name}");
function updateHiddenInput() {
var code = ""
codeInputs.forEach((input) => {
code = code + input.value
})
hiddenInput.value = code;
document.getElementById('error-code').classList.add('hidden');
${resetSubmitError()}
}
codeInputs.forEach((input, index) => {
input.addEventListener('input', (e) => {
var value = e.target.value.replace(/[^0-9]/g, '');
if (value.length > 1) {
e.target.value = value.substring(0, 1);
} else {
e.target.value = value;
}
if (value.length !== 0 && index < codeInputs.length - 1) {
codeInputs[index + 1].focus();
}
updateHiddenInput();
});
input.addEventListener('keyup', (e) => {
if (e.key === 'Backspace' && e.target.value === '' && index > 0) {
codeInputs[index - 1].focus();
updateHiddenInput();
}
});
});
</script>
`}
</section>
)
}

export default CodeInput
8 changes: 8 additions & 0 deletions server/src/views/components/Layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,14 @@ const Layout = ({
font-size: 16px;
color: darkslategray;
}
.code-input {
background-color: white;
border: 1px solid lightgray;
text-align: center;
border-radius: 12px;
width: 42px;
height: 42px;
}
.input {
background-color: white;
border: 1px solid lightgray;
Expand Down
2 changes: 1 addition & 1 deletion server/src/views/scripts/resetError.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { html } from 'hono/html'

const resetSubmitError = () => html`
export const resetSubmitError = () => html`
var submitBtn = document.getElementById('submit-button');
if (submitBtn) submitBtn.disabled = false;
var errorEl = document.getElementById('submit-error');
Expand Down

0 comments on commit 5233a93

Please sign in to comment.