diff --git a/src/components/common/Header/Header.tsx b/src/components/common/Header/Header.tsx index e9a06b9a8..4b2cf43c6 100644 --- a/src/components/common/Header/Header.tsx +++ b/src/components/common/Header/Header.tsx @@ -13,7 +13,7 @@ import s from './Header.module.scss' const Header = memo(() => { const [isFullHeader, setIsFullHeader] = useState(true) - const { visible: visibleModalAuthen, closeModal: closeModalAuthen, openModal: openModalAuthen } = useModalCommon({ initialValue: false }) + const { visible: visibleModalAuthen, closeModal: closeModalAuthen, openModal: openModalAuthen } = useModalCommon({ initialValue: true }) const { visible: visibleModalInfo, closeModal: closeModalInfo, openModal: openModalInfo } = useModalCommon({ initialValue: false }) useEffect(() => { diff --git a/src/components/common/InputCommon/InputCommon.module.scss b/src/components/common/InputCommon/InputCommon.module.scss index 1ef1fdbc7..acfc07647 100644 --- a/src/components/common/InputCommon/InputCommon.module.scss +++ b/src/components/common/InputCommon/InputCommon.module.scss @@ -1,51 +1,94 @@ @import "../../../styles/utilities"; .inputWrap { - @apply flex items-center relative; - .icon { - @apply absolute; - content: ""; - left: 1.6rem; - margin-right: 1.6rem; - svg path { - fill: currentColor; + .inputInner { + @apply flex items-center relative; + .icon { + @apply absolute flex justify-center items-center; + content: ""; + left: 1.6rem; + margin-right: 1.6rem; + svg path { + fill: currentColor; + } } - } - .icon + .inputCommon { - padding-left: 4.8rem; - } - .inputCommon { - @apply block w-full transition-all duration-200 rounded; - padding: 1.2rem 1.6rem; - border: 1px solid var(--border-line); - &:hover, - &:focus, - &:active { - outline: none; - border: 1px solid var(--primary); - @apply shadow-md; + .icon + .inputCommon { + padding-left: 4.8rem; } - &::placeholder { - @apply text-label; - } - - &.custom { - @apply custom-border-radius; - border: 1px solid transparent; - background: var(--gray); + .inputCommon { + @apply block w-full transition-all duration-200 rounded; + padding: 1.2rem 1.6rem; + border: 1px solid var(--border-line); &:hover, &:focus, &:active { + outline: none; border: 1px solid var(--primary); + @apply shadow-md; + } + + &::placeholder { + @apply text-label; + } + + &.custom { + @apply custom-border-radius; + border: 1px solid transparent; + background: var(--gray); + &:hover, + &:focus, + &:active { + border: 1px solid var(--primary); + } + } + &.bgTransparent { + background: rgb(227, 242, 233, 0.3); + color: var(--white); + &::placeholder { + color: var(--white); + } } } - &.bgTransparent { - background: rgb(227, 242, 233, 0.3); - color: var(--white); - &::placeholder { - color: var(--white); + + &.preserve { + @apply flex-row-reverse; + .icon { + left: unset; + right: 1.6rem; + margin-left: 1.6rem; + margin-right: 0; + svg path { + fill: var(--text-label); + } + } + .icon + .inputCommon { + padding-left: 1.6rem; + padding-right: 4.8rem; + } + } + &.success { + .icon { + svg path { + fill: var(--primary); + } + } + } + + &.error { + .icon { + svg path { + fill: var(--negative); + } + } + input { + border-color: var(--negative) !important; } } } + .errorMessage { + @apply caption; + color: var(--negative); + margin-top: 0.4rem; + } } diff --git a/src/components/common/InputCommon/InputCommon.tsx b/src/components/common/InputCommon/InputCommon.tsx index 6a42d5537..943b0a632 100644 --- a/src/components/common/InputCommon/InputCommon.tsx +++ b/src/components/common/InputCommon/InputCommon.tsx @@ -1,5 +1,6 @@ import classNames from 'classnames'; -import React, { forwardRef, useImperativeHandle, useRef } from 'react'; +import React, { forwardRef, useImperativeHandle, useMemo, useRef, useState } from 'react'; +import { IconCheck, IconError, IconPassword, IconPasswordCross } from 'src/components/icons'; import { KEY } from 'src/utils/constanst.utils'; import s from './InputCommon.module.scss'; @@ -14,14 +15,29 @@ interface Props { styleType?: 'default' | 'custom', backgroundTransparent?: boolean, icon?: React.ReactNode, + isIconSuffix?: boolean, + isShowIconSuccess?: boolean, + error?: string, onChange?: (value: string | number) => void, onEnter?: (value: string | number) => void, } const InputCommon = forwardRef(({ value, placeholder, type, styleType = 'default', icon, backgroundTransparent = false, + isIconSuffix, isShowIconSuccess, error, onChange, onEnter }: Props, ref) => { const inputElementRef = useRef(null); + const iconElement = useMemo(() => { + if (error) { + return + } else if (isShowIconSuccess) { + return + } else if (icon) { + return {icon} + } + return <> + }, [icon, error, isShowIconSuccess]) + useImperativeHandle(ref, () => ({ focus: () => { inputElementRef.current?.focus(); @@ -44,23 +60,33 @@ const InputCommon = forwardRef(({ value, placeholder, type, styleTyp } return ( -
+
+
+ {iconElement} + +
{ - icon && {icon} + error &&
{error}
} -
) diff --git a/src/components/common/InputPassword/InputPassword.module.scss b/src/components/common/InputPassword/InputPassword.module.scss new file mode 100644 index 000000000..598620891 --- /dev/null +++ b/src/components/common/InputPassword/InputPassword.module.scss @@ -0,0 +1,10 @@ +.iconPassword { + all: unset; + cursor: pointer; + &:focus { + outline: none; + } + &:focus-visible { + outline: 2px solid var(--text-active); + } +} diff --git a/src/components/common/InputPassword/InputPassword.tsx b/src/components/common/InputPassword/InputPassword.tsx new file mode 100644 index 000000000..83e91cfcc --- /dev/null +++ b/src/components/common/InputPassword/InputPassword.tsx @@ -0,0 +1,40 @@ +import React, { useState } from 'react'; +import { IconPassword, IconPasswordCross } from 'src/components/icons'; +import { Inputcommon } from '..'; +import s from './InputPassword.module.scss'; + +interface Props { + children?: React.ReactNode, + value?: string | number, + placeholder?: string, + styleType?: 'default' | 'custom', + error?: string, + onChange?: (value: string | number) => void, + onEnter?: (value: string | number) => void, +} + +const InputPassword = ({ value, placeholder, styleType = 'default', error, + onChange, onEnter }: Props) => { + const [isShowPassword, setIsShowPassword] = useState(false) + const toggleShowPassword = () => { + setIsShowPassword(!isShowPassword) + } + + return ( + + {isShowPassword ? : } + } + isIconSuffix={true} + onChange={onChange} + onEnter={onEnter} + /> + ) +} + +export default InputPassword diff --git a/src/components/common/ModalAuthenticate/components/FormLogin/FormLogin.tsx b/src/components/common/ModalAuthenticate/components/FormLogin/FormLogin.tsx index de553a6aa..20a1a60ad 100644 --- a/src/components/common/ModalAuthenticate/components/FormLogin/FormLogin.tsx +++ b/src/components/common/ModalAuthenticate/components/FormLogin/FormLogin.tsx @@ -1,12 +1,12 @@ import Link from 'next/link' -import React, { useRef, useEffect } from 'react' -import { Inputcommon, ButtonCommon } from 'src/components/common' +import React, { useEffect, useRef } from 'react' +import { ButtonCommon, Inputcommon } from 'src/components/common' +import InputPassword from 'src/components/common/InputPassword/InputPassword' import { ROUTE } from 'src/utils/constanst.utils' -import SocialAuthen from '../SocialAuthen/SocialAuthen' -import s from '../FormAuthen.module.scss' -import styles from './FormLogin.module.scss' -import classNames from 'classnames' import { CustomInputCommon } from 'src/utils/type.utils' +import s from '../FormAuthen.module.scss' +import SocialAuthen from '../SocialAuthen/SocialAuthen' +import styles from './FormLogin.module.scss' interface Props { isHide: boolean, @@ -26,8 +26,9 @@ const FormLogin = ({ onSwitch, isHide }: Props) => {
- - + +
diff --git a/src/components/common/index.ts b/src/components/common/index.ts index 86b242fb9..5848f41cd 100644 --- a/src/components/common/index.ts +++ b/src/components/common/index.ts @@ -12,6 +12,7 @@ export { default as ViewAllItem} from './ViewAllItem/ViewAllItem' export { default as ItemWishList} from './ItemWishList/ItemWishList' export { default as Logo} from './Logo/Logo' export { default as Inputcommon} from './InputCommon/InputCommon' +export { default as InputPassword} from './InputPassword/InputPassword' export { default as CheckboxCommon} from './CheckboxCommon/CheckboxCommon' export { default as Author} from './Author/Author' export { default as DateTime} from './DateTime/DateTime' diff --git a/src/components/icons/IconCheck.tsx b/src/components/icons/IconCheck.tsx new file mode 100644 index 000000000..cbd1e861c --- /dev/null +++ b/src/components/icons/IconCheck.tsx @@ -0,0 +1,11 @@ +import React from 'react' + +const IconCheck = () => { + return ( + + + + ) +} + +export default IconCheck diff --git a/src/components/icons/IconError.tsx b/src/components/icons/IconError.tsx new file mode 100644 index 000000000..c7c59fb60 --- /dev/null +++ b/src/components/icons/IconError.tsx @@ -0,0 +1,11 @@ +import React from 'react' + +const IconError = () => { + return ( + + + + ) +} + +export default IconError diff --git a/src/components/icons/IconPassword.tsx b/src/components/icons/IconPassword.tsx new file mode 100644 index 000000000..e07c4dc22 --- /dev/null +++ b/src/components/icons/IconPassword.tsx @@ -0,0 +1,11 @@ +import React from 'react' + +const IconPassword = () => { + return ( + + + + ) +} + +export default IconPassword diff --git a/src/components/icons/IconPasswordCross.tsx b/src/components/icons/IconPasswordCross.tsx new file mode 100644 index 000000000..d05bbd713 --- /dev/null +++ b/src/components/icons/IconPasswordCross.tsx @@ -0,0 +1,11 @@ +import React from 'react' + +const IconPasswordCross = () => { + return ( + + + + ) +} + +export default IconPasswordCross diff --git a/src/components/icons/index.ts b/src/components/icons/index.ts index 02b4947cb..d71c1bbec 100644 --- a/src/components/icons/index.ts +++ b/src/components/icons/index.ts @@ -15,3 +15,7 @@ export { default as IconApple } from './IconApple' export { default as ArrowLeft } from './ArrowLeft' export { default as ArrowRight } from './ArrowRight' export { default as Close } from './Close' +export { default as IconPassword } from './IconPassword' +export { default as IconPasswordCross } from './IconPasswordCross' +export { default as IconError } from './IconError' +export { default as IconCheck } from './IconCheck'