diff --git a/src/components/Auth/SignIn.tsx b/src/components/Auth/SignIn.tsx index bb91ba07..d58eecec 100644 --- a/src/components/Auth/SignIn.tsx +++ b/src/components/Auth/SignIn.tsx @@ -1,15 +1,16 @@ -import { Button, Flex, Text, useToast } from '@chakra-ui/react' +import { Button, Flex, Link, Text, useToast } from '@chakra-ui/react' import { useMutation } from '@tanstack/react-query' -import { useState } from 'react' +import { useEffect, useState } from 'react' import { FormProvider, useForm } from 'react-hook-form' import { useTranslation } from 'react-i18next' -import { NavLink, useNavigate } from 'react-router-dom' +import { NavLink, useNavigate, useOutletContext } from 'react-router-dom' import { api, ApiEndpoints, UnverifiedApiError } from '~components/Auth/api' import { ILoginParams } from '~components/Auth/authQueries' import { useAuth } from '~components/Auth/useAuth' import { VerificationPending } from '~components/Auth/Verify' import FormSubmitMessage from '~components/Layout/FormSubmitMessage' import InputPassword from '~components/Layout/InputPassword' +import { AuthOutletContextType } from '~elements/LayoutAuth' import { Routes } from '~src/router/routes' import CustomCheckbox from '../Layout/CheckboxCustom' import InputBasic from '../Layout/InputBasic' @@ -42,9 +43,12 @@ const SignIn = ({ email: emailProp }: { email?: string }) => { const { t } = useTranslation() const toast = useToast() const navigate = useNavigate() + const { setTitle, setSubTitle } = useOutletContext() const methods = useForm({ defaultValues: { email: emailProp }, }) + const [isErrorA, setIsErrorA] = useState(false) + const [isComponentMounted, setIsComponentMounted] = useState(false) const { handleSubmit, watch } = methods const email = watch('email', emailProp) @@ -55,6 +59,20 @@ const SignIn = ({ email: emailProp }: { email?: string }) => { const { mutateAsync: checkVerificationCodeStatus } = useVerificationCodeStatus() const { mutateAsync: resendVerificationCode } = useResendVerificationCode() + useEffect(() => { + setTitle(t('signin_title')) + setSubTitle(t('signin_subtitle')) + setIsComponentMounted(true) + }, []) + + useEffect(() => { + if (isComponentMounted && isError) { + setIsErrorA(true) + } + + return () => setIsErrorA(false) + }, [isError]) + const onSubmit = async (data: FormData) => { await login(data) .then(() => navigate(Routes.dashboard.base)) @@ -111,7 +129,6 @@ const SignIn = ({ email: emailProp }: { email?: string }) => { label={t('email')} placeholder={t('email_placeholder', { defaultValue: 'your@email.com' })} type='email' - required /> { - + {t('forgot_password')} @@ -137,14 +154,12 @@ const SignIn = ({ email: emailProp }: { email?: string }) => { {t('not_registred_yet')} - - - {t('create_account')} - - + + {t('create_account')} + - + ) } diff --git a/src/components/Auth/SignUp.tsx b/src/components/Auth/SignUp.tsx index 3f738feb..032dc977 100644 --- a/src/components/Auth/SignUp.tsx +++ b/src/components/Auth/SignUp.tsx @@ -1,12 +1,14 @@ import { Button, Flex, Link, Text } from '@chakra-ui/react' +import { useEffect } from 'react' import { FormProvider, useForm } from 'react-hook-form' import { Trans, useTranslation } from 'react-i18next' -import { Navigate, NavLink, Link as ReactRouterLink } from 'react-router-dom' +import { Navigate, NavLink, Link as ReactRouterLink, useOutletContext } from 'react-router-dom' import { IRegisterParams } from '~components/Auth/authQueries' import { useAuth } from '~components/Auth/useAuth' import { VerificationPending } from '~components/Auth/Verify' import FormSubmitMessage from '~components/Layout/FormSubmitMessage' import InputPassword from '~components/Layout/InputPassword' +import { AuthOutletContextType } from '~elements/LayoutAuth' import { useSignupFromInvite } from '~src/queries/account' import { Routes } from '~src/router/routes' import CustomCheckbox from '../Layout/CheckboxCustom' @@ -32,6 +34,8 @@ const SignUp = ({ invite }: SignupProps) => { const { t } = useTranslation() const { register } = useAuth() const inviteSignup = useSignupFromInvite(invite?.address) + const { setTitle, setSubTitle } = useOutletContext() + const methods = useForm({ defaultValues: { terms: false, @@ -45,6 +49,11 @@ const SignUp = ({ invite }: SignupProps) => { const isError = register.isError || inviteSignup.isError const error = register.error || inviteSignup.error + useEffect(() => { + setTitle(t('signup_title')) + setSubTitle(t('signup_subtitle')) + }, []) + const onSubmit = (user: FormData) => { if (!invite) { return register.mutate(user) @@ -87,8 +96,13 @@ const SignUp = ({ invite }: SignupProps) => { formValue='email' label={t('email')} placeholder={t('email_placeholder', { defaultValue: 'your@email.com' })} - type='email' - required + validation={{ + required: t('form.error.field_is_required'), + pattern: { + value: /^[^\s@]+@[^\s@]+\.[^\s@]+$/, // Regex para validar emails + message: t('form.error.email_invalid', { defaultValue: 'Invalid email address' }), + }, + }} isDisabled={!!invite} /> { label={t('password')} placeholder={t('password_placeholder')} type='password' - required validation={{ required: t('form.error.field_is_required'), minLength: { @@ -129,11 +142,9 @@ const SignUp = ({ invite }: SignupProps) => { {t('already_member')} - - - {t('signin')} - - + + {t('signin')} + {isError && } diff --git a/src/components/Home/Benefits.tsx b/src/components/Home/Benefits.tsx index 5e35a624..9ef0f4b6 100644 --- a/src/components/Home/Benefits.tsx +++ b/src/components/Home/Benefits.tsx @@ -37,7 +37,7 @@ const Benefits = () => { right='9%' /> - + { > {t('home.clients_title')} + ) } @@ -40,17 +41,17 @@ export const ClientsGrid = (props: GridProps) => ( sm: '20px', md: '80px', }} - maxW={{ base: '100%', sm: '70%', sm2: '80%', lg: '900px' }} + maxW={{ base: '100%', sm: '80%', lg: '900px' }} flexDirection={{ base: 'column', sm: 'row' }} justifyContent='center' - mb={{ base: '60px' }} + mb={{ lg: '60px' }} gridTemplateColumns='repeat(5, 1fr)' - gridRowGap='50px' + gridRowGap={{ base: '0px', sm: '30px', lg: '50px' }} {...props} > - + F.C. Barcelona @@ -58,7 +59,7 @@ export const ClientsGrid = (props: GridProps) => ( - + Omnium Cultural @@ -66,7 +67,7 @@ export const ClientsGrid = (props: GridProps) => ( - + Ajuntament Berga @@ -74,7 +75,7 @@ export const ClientsGrid = (props: GridProps) => ( - + Ajuntament la Bisbal @@ -82,7 +83,7 @@ export const ClientsGrid = (props: GridProps) => ( - + COEC @@ -90,7 +91,7 @@ export const ClientsGrid = (props: GridProps) => ( - + Esquerra Republicana @@ -98,7 +99,7 @@ export const ClientsGrid = (props: GridProps) => ( - + Ajuntament Bellpuig @@ -106,7 +107,7 @@ export const ClientsGrid = (props: GridProps) => ( - + TIC Anoia @@ -114,7 +115,7 @@ export const ClientsGrid = (props: GridProps) => ( - + Decidim @@ -122,7 +123,7 @@ export const ClientsGrid = (props: GridProps) => ( - + Bloock diff --git a/src/components/Layout/CheckboxCustom.tsx b/src/components/Layout/CheckboxCustom.tsx index fd37b372..e740bbc5 100644 --- a/src/components/Layout/CheckboxCustom.tsx +++ b/src/components/Layout/CheckboxCustom.tsx @@ -10,7 +10,7 @@ export interface CheckboxCustomProps { colorScheme?: string } -const CheckboxCustom = ({ formValue, label, required = false, colorScheme = 'brandScheme' }: CheckboxCustomProps) => { +const CheckboxCustom = ({ formValue, label, required = false, colorScheme = 'brand' }: CheckboxCustomProps) => { const { t } = useTranslation() const { register, diff --git a/src/components/Layout/InputBasic.tsx b/src/components/Layout/InputBasic.tsx index ff9c8bff..745514af 100644 --- a/src/components/Layout/InputBasic.tsx +++ b/src/components/Layout/InputBasic.tsx @@ -24,7 +24,7 @@ const InputBasic = ({ formValue, label, required = false, validation = {}, ...pr const errorMessage = errors[formValue]?.message?.toString() || '' return ( - + {label && {label}} {errorMessage || 'Error performing the operation'} diff --git a/src/components/Organization/Create.tsx b/src/components/Organization/Create.tsx index bde8b756..df1d7243 100644 --- a/src/components/Organization/Create.tsx +++ b/src/components/Organization/Create.tsx @@ -92,7 +92,6 @@ export const OrganizationCreate = ({ id='process-create-form' direction='column' gap={6} - maxW='90%' mx='auto' {...props} onSubmit={(e) => { diff --git a/src/components/Organization/Dashboard/AuthBanner.tsx b/src/components/Organization/Dashboard/AuthBanner.tsx index 8b65a5b1..c07c579f 100644 --- a/src/components/Organization/Dashboard/AuthBanner.tsx +++ b/src/components/Organization/Dashboard/AuthBanner.tsx @@ -17,7 +17,7 @@ const AuthBanner = ({ children, ...props }: AuthBannerProps) => { flex={{ base: '1 1 100%', xl: '1 1 50%' }} background='linear-gradient(to bottom, #B5F492, #338B93)' borderBottomLeftRadius={{ xl: '200px' }} - pt={14} + pt={{ base: 20, xl: 0 }} pb={{ xl: 5 }} > @@ -29,25 +29,30 @@ const AuthBanner = ({ children, ...props }: AuthBannerProps) => { }} textAlign='center' h='100%' - maxW='600px' mx='auto' {...props} > {children} - + - + {t('support', { defaultValue: 'Support' })} - + {t('terms_of_use', { defaultValue: 'Terms of use' })} - + {t('blog', { defaultValue: 'Blog' })} diff --git a/src/elements/LayoutAuth.tsx b/src/elements/LayoutAuth.tsx index c23704b0..08c543a3 100644 --- a/src/elements/LayoutAuth.tsx +++ b/src/elements/LayoutAuth.tsx @@ -40,18 +40,24 @@ const LayoutAuth = () => { - + @@ -65,6 +71,8 @@ const LayoutAuth = () => { { {sidebar} - + {t('auth.title', { defaultValue: 'The global voting platform' })} diff --git a/src/elements/account/createOrganization.tsx b/src/elements/account/createOrganization.tsx index 48d629f8..73eaa9a0 100644 --- a/src/elements/account/createOrganization.tsx +++ b/src/elements/account/createOrganization.tsx @@ -22,7 +22,7 @@ const CreateOrganization = () => { } const CreateOrganizationSidebar = () => ( - + Try Vocdoni for free for 7 days @@ -48,10 +48,10 @@ const CreateOrganizationSidebar = () => ( No credit card, no automatic renewal. - - + ) export default CreateOrganization diff --git a/src/theme/colors.ts b/src/theme/colors.ts index e7409d10..fe11ada5 100644 --- a/src/theme/colors.ts +++ b/src/theme/colors.ts @@ -19,7 +19,7 @@ export const colorsBase = { orange: '#FFA500', primary: '#546E39', primary_dark: 'rgba(84, 110, 57, 0.2)', - red: '#C53030', + red: '#FC8181', white: { pure: '#ffffff', dark: '#F5F5F7', @@ -51,6 +51,7 @@ export const colors = { auth: { textColorSecondary: colorsBase.gray.normal, }, + banner_link: colorsBase.white.pure, bg: { light: colorsBase.white.dark, dark: colorsBase.blue.dark2, @@ -408,7 +409,7 @@ export const colors = { dark: 'gray.600', }, }, - + text_area_bg: colorsBase.white.pure, text_area: { toolbar_dark: { bg: '#232323', diff --git a/src/theme/components/card.ts b/src/theme/components/card.ts index 31db3ced..f022c20c 100644 --- a/src/theme/components/card.ts +++ b/src/theme/components/card.ts @@ -173,7 +173,7 @@ export const Card = defineMultiStyleConfig({ body: { p: 0, fontSize: '10px', - minH: '40px', + minH: '50px', span: { display: 'none', diff --git a/src/theme/components/input.ts b/src/theme/components/input.ts index 26060241..9644d23b 100644 --- a/src/theme/components/input.ts +++ b/src/theme/components/input.ts @@ -11,6 +11,13 @@ const baseStyle = definePartsStyle({ _dark: { bgColor: 'input.bg.dark', }, + + _invalid: { + _focusVisible: { + borderColor: 'input.error', + boxShadow: '0px 0px 0px 1px #FC8181', + }, + }, }, element: { diff --git a/src/theme/components/textarea.ts b/src/theme/components/textarea.ts index 12c40c86..854a59c6 100644 --- a/src/theme/components/textarea.ts +++ b/src/theme/components/textarea.ts @@ -3,5 +3,11 @@ import { defineStyleConfig } from '@chakra-ui/react' export const Textarea = defineStyleConfig({ baseStyle: { borderRadius: 'lg', + + bgColor: 'text_area_bg !important', + + _dark: { + bgColor: 'transparent !important', + }, }, })