Skip to content

Commit

Permalink
Merge pull request #35 from opticrd/refactor-to-mui
Browse files Browse the repository at this point in the history
refactor(ui): use vainilla Material UI where possible
  • Loading branch information
gustavovalverde authored Jun 19, 2023
2 parents d35beca + 15cd372 commit 6fa995f
Show file tree
Hide file tree
Showing 12 changed files with 530 additions and 4,489 deletions.
9 changes: 2 additions & 7 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,8 @@
"@aws-amplify/ui-react-liveness": "^1.0.1",
"@aws-sdk/client-rekognition": "^3.354.0",
"@babel/core": "*",
"@babel/preset-env": "^7.1.6",
"@emotion/react": "^11.10.6",
"@emotion/styled": "^11.10.6",
"@fontsource/roboto": "^4.5.8",
"@hookform/resolvers": "2.9.7",
"@mui/icons-material": "^5.11.11",
"@mui/material": "^5.11.12",
Expand All @@ -31,15 +29,11 @@
"hibp": "^13.0.0",
"next": "13.2.3",
"next-recaptcha-v3": "^1.1.5",
"prop-types": ">=15.7.0",
"react": "18.2.0",
"react-dom": "18.2.0",
"react-hook-form": "7.34.0",
"react-native": ">=0.56",
"sharp": "^0.32.1",
"sweetalert2": "11.4.8",
"typescript": "4.9.5",
"yup": "0.32.11"
"yup": "^1.2.0"
},
"devDependencies": {
"@types/cookie": "^0.5.1",
Expand All @@ -53,6 +47,7 @@
"eslint-import-resolver-typescript": "^3.5.5",
"eslint-plugin-import": "^2.26.0",
"eslint-plugin-prettier": "^4.2.1",
"install-peers": "^1.0.4",
"prettier": ">=2.0.0"
}
}
66 changes: 33 additions & 33 deletions src/components/biometric/displayText.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,9 @@ export const defaultErrorDisplayText = {
timeoutHeaderText: 'Se acabó el tiempo',
timeoutMessageText:
'La cara no llenó el óvalo dentro del límite de tiempo. Vuelva a intentarlo y llene completamente el óvalo con la cara en 7 segundos.',
faceDistanceHeaderText: 'Comprobación fallida durante la cuenta atrás',
faceDistanceHeaderText: 'Comprobación fallida durante la cuenta regresiva',
faceDistanceMessageText:
'Evite acercarse durante la cuenta regresiva y asegúrese de que solo una cara esté frente a la cámara.',
'Evite acercarse durante la cuenta regresiva y asegúrese de que solo haya una cara frente a la cámara.',
clientHeaderText: 'Error del cliente',
clientMessageText: 'Verificación fallida debido a un problema con el cliente',
serverHeaderText: 'Problema del servidor',
Expand All @@ -69,54 +69,54 @@ export type ErrorDisplayTextFoo = typeof defaultErrorDisplayText;
export type ErrorDisplayText = Partial<ErrorDisplayTextFoo>;

export const defaultLivenessDisplayText: Required<LivenessDisplayText> = {
instructionsHeaderHeadingText: 'Liveness check',
instructionsHeaderHeadingText: 'Prueba de vida',
instructionsHeaderBodyText:
'You will go through a face verification process to prove that you are a real person.',
instructionsBeginCheckText: 'Begin check',
photosensitivyWarningHeadingText: 'Photosensitivity warning',
'Ahora va a realizar un proceso de verificación facial para demostrar que es una persona real.',
instructionsBeginCheckText: 'Iniciar prueba',
photosensitivyWarningHeadingText: 'Alerta de fotosensibilidad',
photosensitivyWarningBodyText:
'This check displays colored lights. Use caution if you are photosensitive.',
'Esta comprobación muestra luces de colores. Tenga cuidado si es fotosensible.',
photosensitivyWarningInfoText:
'A small percentage of individuals may experience epileptic seizures when exposed to colored lights. Use caution if you, or anyone in your family, have an epileptic condition.',
instructionListHeadingText: 'Follow the instructions to complete the check:',
goodFitCaptionText: 'Good fit',
'Un pequeño porcentaje de personas puede experimentar convulsiones epilépticas cuando se exponen a luces de colores. Tenga cuidado si usted o alguien de su familia tiene alguna condición epiléptica.',
instructionListHeadingText:
'Siga las instrucciones para completar la verificación:',
goodFitCaptionText: 'Bien encajado',
goodFitAltText:
"Ilustration of a person's face, perfectly fitting inside of an oval.",
tooFarCaptionText: 'Too far',
'Ilustración de la cara de una persona, encajando perfectamente dentro de un óvalo.',
tooFarCaptionText: 'Demasiado lejos',
tooFarAltText:
"Illustration of a person's face inside of an oval; there is a gap between the perimeter of the face and the boundaries of the oval.",
'Ilustración de la cara de una persona dentro de un óvalo; hay un espacio entre el perímetro de la cara y los límites del óvalo.',
instructionListStepOneText:
'When an oval appears, fill the oval with your face within 7 seconds.',
instructionListStepTwoText: "Maximize your screen's brightness.",
'Cuando el óvalo aparezca, llénelo con su cara en 7 segundos.',
instructionListStepTwoText: 'Maximice el brillo de su pantalla.',
instructionListStepThreeText:
'Make sure your face is not covered with sunglasses or a mask.',
'Asegúrese de que su cara no esté cubierta con gafas de sol o una máscara.',
instructionListStepFourText:
'Move to a well-lit place that is not in direct sunlight.',
'Muévase a un lugar bien iluminado que no esté expuesto a la luz solar directa.',
cameraMinSpecificationsHeadingText:
'Camera does not meet minimum specifications',
'La cámara no cumple con las especificaciones mínimas',
cameraMinSpecificationsMessageText:
'Camera must support at least 320*240 resolution and 15 frames per second.',
cameraNotFoundHeadingText: 'Camera not accessible.',
'La cámara debe admitir una resolución de al menos 320 * 240 y 15 fotogramas por segundo.',
cameraNotFoundHeadingText: 'Cámara no accesible',
cameraNotFoundMessageText:
'Verifique que la cámara esté conectada y que los permisos de la cámara estén habilitados en la configuración antes de volver a intentarlo.',
retryCameraPermissionsText: 'Procesar de nuevo',
cancelLivenessCheckText: 'Cancelar comprobación de vitalidad',
recordingIndicatorText: 'Grabación',
hintMoveFaceFrontOfCameraText: 'Mover la cara frente a la cámara',
hintTooManyFacesText:
'Asegúrese de que solo una cara esté frente a la cámara',
cancelLivenessCheckText: 'Cancelar prueba de vida',
recordingIndicatorText: 'Grabando',
hintMoveFaceFrontOfCameraText: 'Posicione la cara frente a la cámara',
hintTooManyFacesText: 'Asegúrese que solo una cara esté frente a la cámara',
hintFaceDetectedText: 'Cara detectada',
hintCanNotIdentifyText: 'Mover la cara frente a la cámara',
hintTooCloseText: 'Muévete mas atrás',
hintTooFarText: 'Muévete mas cerca',
hintCanNotIdentifyText: 'No podemos identificar su cara frente a la cámara',
hintTooCloseText: 'Muévase más atrás',
hintTooFarText: 'Muévase más cerca',
hintHoldFacePositionCountdownText:
'Mantener la posición de la cara durante la cuenta regresiva',
'Mantenga la posición de la cara durante la cuenta regresiva',
hintConnectingText: 'Conectando...',
hintVerifyingText: 'Verificando...',
hintIlluminationTooBrightText: 'Mover al área de atenuación',
hintIlluminationTooDarkText: 'Mover a un área más brillante',
hintIlluminationNormalText: 'Condiciones de iluminación normales',
hintHoldFaceForFreshnessText: 'Quédate quieto',
hintIlluminationTooBrightText: 'Muévase a un área con menos iluminación',
hintIlluminationTooDarkText: 'Muévase a un área con mayor iluminación',
hintIlluminationNormalText: 'Condiciones de iluminación correctas',
hintHoldFaceForFreshnessText: 'Quédese quieto',
...defaultErrorDisplayText,
};

Expand Down
17 changes: 9 additions & 8 deletions src/components/biometric/face-liveness-detector.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { Loader, ThemeProvider } from '@aws-amplify/ui-react';
import React from 'react';
import { useState, useEffect } from 'react';

import { AlertErrorMessage } from '../elements/alert';
import { useSnackbar } from '@/components/elements/alert';
import { defaultLivenessDisplayText } from './displayText';

export function LivenessQuickStartReact({ handleNextForm, cedula }: any) {
Expand All @@ -12,6 +12,7 @@ export function LivenessQuickStartReact({ handleNextForm, cedula }: any) {
const [loading, setLoading] = useState<boolean>(true);
const [error, setError] = useState<Error | null>(null);
const [sessionId, setSessionId] = useState<string | null>(null);
const { AlertError } = useSnackbar();

const fetchCreateLiveness = async () => {
const response = await fetch(`/api/biometric`, { method: 'POST' });
Expand Down Expand Up @@ -48,14 +49,14 @@ export function LivenessQuickStartReact({ handleNextForm, cedula }: any) {
});
}, []);

useEffect(() => {
if (error) {
AlertError('No se ha podido validar correctamente la identidad.');
}
}, [error, AlertError]);

return (
<>
{error && (
<AlertErrorMessage
type="info"
message="No se ha podido validar correctamente la identidad."
/>
)}
<br />
<ThemeProvider>
{loading ? (
Expand All @@ -68,7 +69,7 @@ export function LivenessQuickStartReact({ handleNextForm, cedula }: any) {
onUserCancel={onUserCancel}
onError={(error) => setError(error)}
onAnalysisComplete={handleAnalysisComplete}
disableInstructionScreen={true}
disableInstructionScreen={false}
displayText={defaultLivenessDisplayText}
/>
)
Expand Down
97 changes: 66 additions & 31 deletions src/components/elements/alert/index.tsx
Original file line number Diff line number Diff line change
@@ -1,39 +1,74 @@
import Swal from 'sweetalert2';
import Alert from '@mui/material/Alert';
import React, { createContext, useContext, useState } from 'react';
import Snackbar from '@mui/material/Snackbar';
import MuiAlert, { AlertProps } from '@mui/material/Alert';

interface IPropsAlertErrorMessage {
message: string;
type: 'error' | 'warning' | 'info' | 'success';
interface SnackbarContextProps {
openSnackbar: (message: string, severity: AlertProps['severity']) => void;
}

export const AlertErrorMessage = ({
message,
type,
}: IPropsAlertErrorMessage) => <Alert severity={type}>{message}</Alert>;

export const AlertError = (text?: string) => {
return Swal.fire({
icon: 'error',
title: 'Error',
text: text ? text : 'Ocurrió un error al procesar la solicitud',
confirmButtonColor: '#003670',
});
};
// Create context with default undefined value
const SnackbarContext = createContext<SnackbarContextProps | undefined>(
undefined
);

interface SnackbarProviderProps {
children?: React.ReactNode;
}

export const AlertWarning = (text: string) => {
return Swal.fire({
icon: 'warning',
title: 'Aviso',
text: text,
confirmButtonColor: '#003670',
export const SnackbarProvider = ({ children }: SnackbarProviderProps) => {
const [snackbarConfig, setSnackbarConfig] = useState({
open: false,
message: '',
severity: 'success' as AlertProps['severity'],
});

// Open snackbar
const openSnackbar = (message: string, severity: AlertProps['severity']) => {
setSnackbarConfig({ open: true, message, severity });
};

// Close snackbar
const closeSnackbar = () => {
setSnackbarConfig((prevState) => ({ ...prevState, open: false }));
};

return (
<SnackbarContext.Provider value={{ openSnackbar }}>
<Snackbar
open={snackbarConfig.open}
autoHideDuration={6000}
onClose={closeSnackbar}
>
<MuiAlert
onClose={closeSnackbar}
severity={snackbarConfig.severity}
variant="filled"
>
{snackbarConfig.message}
</MuiAlert>
</Snackbar>
{children}
</SnackbarContext.Provider>
);
};

export const AlertSuccess = (text?: string) => {
return Swal.fire({
icon: 'success',
title: 'Correcto',
text: text ? text : 'Proceso realizado correctamente',
confirmButtonColor: '#003670',
});
export const useSnackbar = () => {
const context = useContext(SnackbarContext);

if (!context) {
throw new Error('useSnackbar must be used within a SnackbarProvider');
}

const { openSnackbar } = context;

return {
AlertError: (text?: string) =>
openSnackbar(
text || 'Ocurrió un error al procesar la solicitud',
'error'
),
AlertWarning: (text: string) => openSnackbar(text, 'warning'),
AlertSuccess: (text: string) =>
openSnackbar(text || 'Proceso realizado correctamente', 'success'),
};
};
15 changes: 8 additions & 7 deletions src/pages/_app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { ThemeProvider } from '@mui/material/styles';
import type { AppProps } from 'next/app';
import { Amplify } from 'aws-amplify';
import { ReCaptchaProvider } from "next-recaptcha-v3";
import { SnackbarProvider } from '../components/elements/alert';
import Head from 'next/head';

import Layout from '../components/layout';
Expand All @@ -22,13 +23,13 @@ export default function App({ Component, pageProps }: AppProps) {
</Head>
<ThemeProvider theme={theme}>
<CssBaseline />
<Layout>
<ReCaptchaProvider
useEnterprise
>
<Component {...pageProps} />
</ReCaptchaProvider>
</Layout>
<SnackbarProvider>
<Layout>
<ReCaptchaProvider useEnterprise>
<Component {...pageProps} />
</ReCaptchaProvider>
</Layout>
</SnackbarProvider>
</ThemeProvider>
</>
);
Expand Down
4 changes: 2 additions & 2 deletions src/pages/register/registered/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,8 @@ export default function Index() {
<br />
<TextBody textCenter>
Revisa tu correo y haz clic en el enlace de confirmación, luego
podras ver, realizar tramites y solicitar servicios
gubernamentales con una sola cuenta y contraseña.
realizar tramites y solicitar servicios gubernamentales
con una sola cuenta y contraseña.
</TextBody>
<br />
</GridItem>
Expand Down
Loading

0 comments on commit 6fa995f

Please sign in to comment.