diff --git a/pages/index.tsx b/pages/index.tsx index 1d3072ef7..7ed22f1bc 100644 --- a/pages/index.tsx +++ b/pages/index.tsx @@ -1,6 +1,6 @@ -import { Layout } from 'src/components/common' -import { HomeBanner, HomeCollection, HomeCTA, HomeSubscribe, HomeVideo, HomeCategories, HomeFeature, HomeRecipe } from 'src/components/modules/home'; +import { Layout } from 'src/components/common'; +import { HomeBanner, HomeCategories, HomeCollection, HomeCTA, HomeFeature, HomeRecipe, HomeSubscribe, HomeVideo } from 'src/components/modules/home'; export default function Home() { return ( @@ -13,6 +13,9 @@ export default function Home() { + + // todo: uncomment + {/* */} ) } diff --git a/src/components/common/Header/Header.tsx b/src/components/common/Header/Header.tsx index 12d656026..4b2cf43c6 100644 --- a/src/components/common/Header/Header.tsx +++ b/src/components/common/Header/Header.tsx @@ -3,6 +3,7 @@ import React, { memo, useEffect, useState } from 'react' import { useModalCommon } from 'src/components/hooks/useModalCommon' import { isMobile } from 'src/utils/funtion.utils' import ModalAuthenticate from '../ModalAuthenticate/ModalAuthenticate' +import ModalCreateUserInfo from '../ModalCreateUserInfo/ModalCreateUserInfo' import HeaderHighLight from './components/HeaderHighLight/HeaderHighLight' import HeaderMenu from './components/HeaderMenu/HeaderMenu' import HeaderSubMenu from './components/HeaderSubMenu/HeaderSubMenu' @@ -12,7 +13,8 @@ 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(() => { window.addEventListener('scroll', handleScroll) @@ -35,12 +37,15 @@ const Header = memo(() => {
- +
+ ) }) diff --git a/src/components/common/Header/components/HeaderMenu/HeaderMenu.tsx b/src/components/common/Header/components/HeaderMenu/HeaderMenu.tsx index a5ef71951..969964608 100644 --- a/src/components/common/Header/components/HeaderMenu/HeaderMenu.tsx +++ b/src/components/common/Header/components/HeaderMenu/HeaderMenu.tsx @@ -11,14 +11,19 @@ interface Props { children?: any, isFull: boolean, openModalAuthen: () => void, + openModalInfo: () => void, } -const HeaderMenu = memo(({ isFull, openModalAuthen }: Props) => { +const HeaderMenu = memo(({ isFull, openModalAuthen, openModalInfo }: Props) => { const optionMenu = useMemo(() => [ { onClick: openModalAuthen, name: 'Login (Demo)', }, + { + onClick: openModalInfo, + name: 'Create User Info (Demo)', + }, { link: ROUTE.ACCOUNT, name: 'Account', 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/MenuDropdown/MenuDropdown.module.scss b/src/components/common/MenuDropdown/MenuDropdown.module.scss index ca79464e1..8fc270b2a 100644 --- a/src/components/common/MenuDropdown/MenuDropdown.module.scss +++ b/src/components/common/MenuDropdown/MenuDropdown.module.scss @@ -78,7 +78,7 @@ @apply block; } &:hover { - @apply bg-primary-lightest; + @apply bg-gray; color: var(--primary); } } diff --git a/src/components/common/ModalAuthenticate/components/FormAuthen.module.scss b/src/components/common/ModalAuthenticate/components/FormAuthen.module.scss index bdfc69387..2ec8bf91f 100644 --- a/src/components/common/ModalAuthenticate/components/FormAuthen.module.scss +++ b/src/components/common/ModalAuthenticate/components/FormAuthen.module.scss @@ -1,17 +1,12 @@ +@import '../../../../styles/utilities'; + .formAuthen { - @apply bg-white w-full; + @apply bg-white w-full u-form; .inner { @screen md { - max-width: 52rem; + width: 60rem; margin: auto; } - .body { - > div { - &:not(:last-child) { - margin-bottom: 1.6rem; - } - } - } .others { @apply font-bold text-center; margin-top: 4rem; diff --git a/src/components/common/ModalAuthenticate/components/FormLogin/FormLogin.tsx b/src/components/common/ModalAuthenticate/components/FormLogin/FormLogin.tsx index 7ef3ec9ba..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, @@ -23,14 +23,12 @@ const FormLogin = ({ onSwitch, isHide }: Props) => { }, [isHide]) return ( -
+
- - + +
diff --git a/src/components/common/ModalAuthenticate/components/FormRegister/FormRegister.tsx b/src/components/common/ModalAuthenticate/components/FormRegister/FormRegister.tsx index 1624f2c1c..40d4ef355 100644 --- a/src/components/common/ModalAuthenticate/components/FormRegister/FormRegister.tsx +++ b/src/components/common/ModalAuthenticate/components/FormRegister/FormRegister.tsx @@ -24,7 +24,6 @@ const FormRegister = ({ onSwitch, isHide }: Props) => {
diff --git a/src/components/common/ModalCommon/ModalCommon.module.scss b/src/components/common/ModalCommon/ModalCommon.module.scss index d4967b04e..87900b1a1 100644 --- a/src/components/common/ModalCommon/ModalCommon.module.scss +++ b/src/components/common/ModalCommon/ModalCommon.module.scss @@ -8,7 +8,7 @@ @apply flex justify-center items-center min-h-screen; .modal{ @apply inline-block align-bottom bg-white relative; - max-width: 60rem; + max-width: 66.4rem; padding: 3.2rem; box-shadow: 0px 8px 16px rgba(0, 0, 0, 0.24); border-radius: 1.2rem; @@ -17,7 +17,7 @@ } .title{ @apply font-heading heading-3; - padding: 0 0.8rem 0 0.8rem; + padding: 0 1.6rem 0 0.8rem; } .close{ @apply absolute; diff --git a/src/components/common/ModalCreateUserInfo/ModalCreateUserInfo.module.scss b/src/components/common/ModalCreateUserInfo/ModalCreateUserInfo.module.scss new file mode 100644 index 000000000..199028061 --- /dev/null +++ b/src/components/common/ModalCreateUserInfo/ModalCreateUserInfo.module.scss @@ -0,0 +1,19 @@ +@import "../../../styles/utilities"; + +.formUserInfo { + @apply u-form; + .inner { + @screen md { + width: 60rem; + margin: auto; + } + .bottom { + @apply grid grid-cols-2; + margin-top: 4rem; + grid-gap: 1.6rem; + > button { + @apply w-full; + } + } + } +} diff --git a/src/components/common/ModalCreateUserInfo/ModalCreateUserInfo.tsx b/src/components/common/ModalCreateUserInfo/ModalCreateUserInfo.tsx new file mode 100644 index 000000000..85817c930 --- /dev/null +++ b/src/components/common/ModalCreateUserInfo/ModalCreateUserInfo.tsx @@ -0,0 +1,46 @@ +import classNames from 'classnames'; +import Link from 'next/link'; +import React, { useRef } from 'react'; +import { useModalCommon } from 'src/components/hooks/useModalCommon'; +import { CustomInputCommon } from 'src/utils/type.utils'; +import { Inputcommon } from '..'; +import ButtonCommon from '../ButtonCommon/ButtonCommon'; +import ModalCommon from '../ModalCommon/ModalCommon'; +import s from './ModalCreateUserInfo.module.scss'; + +// todo: remove +interface Props { + demoVisible: boolean, + demoCloseModal: () => void, +} + + +const ModalCreateUserInfo = ({ demoVisible: visible, demoCloseModal: closeModal }: Props) => { + // const { visible, closeModal } = useModalCommon({ initialValue: false}) + const firstInputRef = useRef(null) + + return ( + +
+
+
+ + +
+ {/* todo: select, not input */} + + +
+ +
+
+ Skip + Submit +
+
+
+
+ ); +} + +export default ModalCreateUserInfo; \ No newline at end of file diff --git a/src/components/common/index.ts b/src/components/common/index.ts index dc0288966..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' @@ -28,3 +29,4 @@ export { default as NotiMessage} from './NotiMessage/NotiMessage' export { default as VideoPlayer} from './VideoPlayer/VideoPlayer' export { default as SelectCommon} from './SelectCommon/SelectCommon' export { default as ModalCommon} from './ModalCommon/ModalCommon' +export { default as ModalCreateUserInfo} from './ModalCreateUserInfo/ModalCreateUserInfo' 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 b272e9a83..949b1f3b1 100644 --- a/src/components/icons/index.ts +++ b/src/components/icons/index.ts @@ -16,3 +16,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' diff --git a/src/styles/_utilities.scss b/src/styles/_utilities.scss index 93291dc3a..26cea17c0 100644 --- a/src/styles/_utilities.scss +++ b/src/styles/_utilities.scss @@ -80,7 +80,7 @@ font-size: 10px; line-height: 16px; } - + .spacing-horizontal { padding-left: 2rem; padding-right: 2rem; @@ -119,4 +119,22 @@ .font-logo { font-family: var(--font-logo); } + + .u-form { + .body { + > div { + &:not(:last-child) { + margin-bottom: 1.6rem; + } + } + .line { + @apply flex justify-between items-center; + > div { + &:not(:last-child) { + margin-right: 1.6rem; + } + } + } + } + } }