Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8038744dc1 |
@@ -5,13 +5,10 @@ import { authenticateUser, createUser } from '../turnkey-backend';
|
|||||||
|
|
||||||
const router = Router();
|
const router = Router();
|
||||||
|
|
||||||
//
|
|
||||||
// Access Code
|
|
||||||
//
|
|
||||||
router.post('/accesscode', async (req, res) => {
|
router.post('/accesscode', async (req, res) => {
|
||||||
console.log('Access Code', req.body);
|
console.log('Access Code', req.body);
|
||||||
const { accesscode } = req.body;
|
const { accesscode } = req.body;
|
||||||
if (accesscode === '44444') {
|
if (accesscode === '444444') {
|
||||||
return res.send({ isValid: true });
|
return res.send({ isValid: true });
|
||||||
} else {
|
} else {
|
||||||
return res.sendStatus(204);
|
return res.sendStatus(204);
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import { Router } from 'express';
|
|||||||
const router = Router();
|
const router = Router();
|
||||||
|
|
||||||
router.get('/version', async (req, res) => {
|
router.get('/version', async (req, res) => {
|
||||||
return res.send({ version: '0.0.8' });
|
return res.send({ version: '0.0.7' });
|
||||||
});
|
});
|
||||||
|
|
||||||
export default router;
|
export default router;
|
||||||
|
|||||||
@@ -1,117 +0,0 @@
|
|||||||
import { useEffect, useRef } from 'react';
|
|
||||||
import { Input } from '../Input';
|
|
||||||
|
|
||||||
export interface VerifyCodeInputProps {
|
|
||||||
code: string;
|
|
||||||
setCode: (code: string) => void;
|
|
||||||
submitCode: () => void;
|
|
||||||
loading: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const VerifyCodeInput = ({
|
|
||||||
code,
|
|
||||||
setCode,
|
|
||||||
submitCode,
|
|
||||||
loading,
|
|
||||||
}: VerifyCodeInputProps) => {
|
|
||||||
const inputRefs = useRef<(HTMLInputElement | null)[]>([]);
|
|
||||||
|
|
||||||
const handlePaste = (
|
|
||||||
e: React.ClipboardEvent<HTMLInputElement>,
|
|
||||||
i: number,
|
|
||||||
) => {
|
|
||||||
e.preventDefault();
|
|
||||||
const pasteData = e.clipboardData.getData('text').replace(/\D/g, ''); // Only digits
|
|
||||||
if (pasteData.length > 0) {
|
|
||||||
let newCodeArray = code.split('');
|
|
||||||
for (let j = 0; j < pasteData.length && i + j < 6; j++) {
|
|
||||||
newCodeArray[i + j] = pasteData[j];
|
|
||||||
}
|
|
||||||
const newCode = newCodeArray.join('');
|
|
||||||
setCode(newCode);
|
|
||||||
const nextIndex = Math.min(i + pasteData.length, 5);
|
|
||||||
const nextInput = inputRefs.current[nextIndex];
|
|
||||||
if (nextInput) nextInput.focus();
|
|
||||||
if (!newCode.includes(' ')) {
|
|
||||||
submitCode();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleKeyDown = (
|
|
||||||
e: React.KeyboardEvent<HTMLInputElement>,
|
|
||||||
i: number,
|
|
||||||
) => {
|
|
||||||
if (e.altKey || e.ctrlKey || e.metaKey || e.shiftKey) return;
|
|
||||||
|
|
||||||
if (e.key === 'Backspace') {
|
|
||||||
e.preventDefault();
|
|
||||||
const isEmpty = code[i] === ' ';
|
|
||||||
const newCode = !isEmpty
|
|
||||||
? code.slice(0, i) + ' ' + code.slice(i + 1, 6)
|
|
||||||
: code.slice(0, i - 1) + ' ' + code.slice(i, 6);
|
|
||||||
|
|
||||||
setCode(newCode.slice(0, 6));
|
|
||||||
|
|
||||||
if (i === 0 || !isEmpty) return;
|
|
||||||
const prev = inputRefs.current[i - 1];
|
|
||||||
if (prev) prev.focus();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!e.key.match(/[0-9]/)) return;
|
|
||||||
|
|
||||||
e.preventDefault(); // Prevent the default event to avoid duplicate input
|
|
||||||
|
|
||||||
const newCode = code.slice(0, i) + e.key + code.slice(i + 1, 6);
|
|
||||||
setCode(newCode);
|
|
||||||
|
|
||||||
if (i === 5) {
|
|
||||||
submitCode();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const next = inputRefs.current[i + 1];
|
|
||||||
if (next) next.focus();
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleChange = (e: React.ChangeEvent<HTMLInputElement>, i: number) => {
|
|
||||||
const value = e.target.value.slice(-1);
|
|
||||||
if (!value.match(/[0-9]/)) return;
|
|
||||||
|
|
||||||
const newCode = code.slice(0, i) + value + code.slice(i + 1, 6);
|
|
||||||
setCode(newCode);
|
|
||||||
|
|
||||||
if (i < 5) {
|
|
||||||
const next = inputRefs.current[i + 1];
|
|
||||||
if (next) next.focus();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!newCode.includes(' ')) {
|
|
||||||
submitCode();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (inputRefs.current[0]) {
|
|
||||||
inputRefs.current[0].focus();
|
|
||||||
}
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="flex gap-2">
|
|
||||||
{code.split('').map((char, i) => (
|
|
||||||
<Input
|
|
||||||
key={i}
|
|
||||||
value={char === ' ' ? '' : char}
|
|
||||||
ref={(el) => (inputRefs.current[i] = el)}
|
|
||||||
onChange={(e) => handleChange(e, i)}
|
|
||||||
onPaste={(e) => handlePaste(e, i)}
|
|
||||||
onKeyDown={(e) => handleKeyDown(e, i)}
|
|
||||||
disabled={!!loading}
|
|
||||||
style={{ textAlign: 'center' }} // Add this line to center text
|
|
||||||
/>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
export { VerifyCodeInput } from './VerifyCodeInput';
|
|
||||||
@@ -6,7 +6,7 @@ import {
|
|||||||
LoaderIcon,
|
LoaderIcon,
|
||||||
} from 'components/shared/CustomIcon';
|
} from 'components/shared/CustomIcon';
|
||||||
import { WavyBorder } from 'components/shared/WavyBorder';
|
import { WavyBorder } from 'components/shared/WavyBorder';
|
||||||
import { VerifyCodeInput } from 'components/shared/VerifyCodeInput';
|
import { Input } from 'components/shared/Input';
|
||||||
import { verifyAccessCode } from 'utils/accessCode';
|
import { verifyAccessCode } from 'utils/accessCode';
|
||||||
|
|
||||||
type AccessMethod = 'accesscode' | 'passkey';
|
type AccessMethod = 'accesscode' | 'passkey';
|
||||||
@@ -20,7 +20,7 @@ type AccessCodeProps = {
|
|||||||
export const AccessCode: React.FC<AccessCodeProps> = ({
|
export const AccessCode: React.FC<AccessCodeProps> = ({
|
||||||
onCorrectAccessCode,
|
onCorrectAccessCode,
|
||||||
}) => {
|
}) => {
|
||||||
const [accessCode, setAccessCode] = useState(' ');
|
const [accessCode, setAccessCode] = useState('');
|
||||||
const [error, setError] = useState<Err | null>();
|
const [error, setError] = useState<Err | null>();
|
||||||
const [accessMethod, setAccessMethod] = useState<AccessMethod | false>(false);
|
const [accessMethod, setAccessMethod] = useState<AccessMethod | false>(false);
|
||||||
|
|
||||||
@@ -28,9 +28,6 @@ export const AccessCode: React.FC<AccessCodeProps> = ({
|
|||||||
setAccessMethod('accesscode');
|
setAccessMethod('accesscode');
|
||||||
try {
|
try {
|
||||||
const isValidAccessCode = await verifyAccessCode(accessCode);
|
const isValidAccessCode = await verifyAccessCode(accessCode);
|
||||||
|
|
||||||
// add a pause for ux
|
|
||||||
await new Promise((resolve) => setTimeout(resolve, 250));
|
|
||||||
if (isValidAccessCode) {
|
if (isValidAccessCode) {
|
||||||
localStorage.setItem('accessCode', accessCode);
|
localStorage.setItem('accessCode', accessCode);
|
||||||
onCorrectAccessCode();
|
onCorrectAccessCode();
|
||||||
@@ -46,7 +43,7 @@ export const AccessCode: React.FC<AccessCodeProps> = ({
|
|||||||
}
|
}
|
||||||
|
|
||||||
const loading = accessMethod;
|
const loading = accessMethod;
|
||||||
const isValidAccessCodeLength = accessCode.trim().length === 5;
|
const isValidAccessCodeLength = accessCode.length === 6;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
@@ -59,11 +56,10 @@ export const AccessCode: React.FC<AccessCodeProps> = ({
|
|||||||
<div className="self-stretch p-4 xs:p-6 flex-col justify-center items-center gap-8 flex">
|
<div className="self-stretch p-4 xs:p-6 flex-col justify-center items-center gap-8 flex">
|
||||||
<div className="self-stretch flex-col gap-8 flex">
|
<div className="self-stretch flex-col gap-8 flex">
|
||||||
<div className="flex-col justify-start items-start gap-2 inline-flex">
|
<div className="flex-col justify-start items-start gap-2 inline-flex">
|
||||||
<VerifyCodeInput
|
<Input
|
||||||
loading={!!loading}
|
value={accessCode}
|
||||||
code={accessCode}
|
onChange={(e) => setAccessCode(e.target.value)}
|
||||||
setCode={setAccessCode}
|
disabled={!!loading}
|
||||||
submitCode={validateAccessCode}
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<Button
|
<Button
|
||||||
@@ -74,7 +70,9 @@ export const AccessCode: React.FC<AccessCodeProps> = ({
|
|||||||
<ArrowRightCircleFilledIcon height="16" />
|
<ArrowRightCircleFilledIcon height="16" />
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
onClick={validateAccessCode}
|
onClick={() => {
|
||||||
|
validateAccessCode();
|
||||||
|
}}
|
||||||
variant={'secondary'}
|
variant={'secondary'}
|
||||||
disabled={!accessCode || !isValidAccessCodeLength || !!loading}
|
disabled={!accessCode || !isValidAccessCodeLength || !!loading}
|
||||||
>
|
>
|
||||||
@@ -84,10 +82,7 @@ export const AccessCode: React.FC<AccessCodeProps> = ({
|
|||||||
<div className="flex flex-col gap-3">
|
<div className="flex flex-col gap-3">
|
||||||
<div className="justify-center items-center gap-2 inline-flex">
|
<div className="justify-center items-center gap-2 inline-flex">
|
||||||
<div className="text-red-500 text-sm">
|
<div className="text-red-500 text-sm">
|
||||||
Error: {error.message}.{' '}
|
Error: {error.message}
|
||||||
<a href="/signup" className="underline">
|
|
||||||
Try again?
|
|
||||||
</a>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user