diff --git a/frontend/src/bundles/common/components/button/button.tsx b/frontend/src/bundles/common/components/button/button.tsx index 5cc794ede..ec9afd898 100644 --- a/frontend/src/bundles/common/components/button/button.tsx +++ b/frontend/src/bundles/common/components/button/button.tsx @@ -11,6 +11,7 @@ type Properties = { isDisabled?: boolean; className?: string | undefined; onClick?: () => void; + leftIcon?: React.ReactElement; } & ChakraProperties; const Button: React.FC = ({ @@ -20,6 +21,7 @@ const Button: React.FC = ({ size = 'md', isDisabled = false, className, + leftIcon, onClick, ...ChakraProperties }) => ( @@ -31,6 +33,7 @@ const Button: React.FC = ({ isDisabled={isDisabled} className={className} onClick={onClick} + {...(leftIcon ? { leftIcon } : {})} {...ChakraProperties} > {label} diff --git a/frontend/src/bundles/common/components/components.ts b/frontend/src/bundles/common/components/components.ts index 0d391b786..3f948daf2 100644 --- a/frontend/src/bundles/common/components/components.ts +++ b/frontend/src/bundles/common/components/components.ts @@ -47,6 +47,7 @@ export { IconButton, Image, InputGroup, + InputLeftElement, InputRightElement, Button as LibraryButton, Input as LibraryInput, diff --git a/frontend/src/bundles/common/components/input/input.tsx b/frontend/src/bundles/common/components/input/input.tsx index a27a862be..451e1aea5 100644 --- a/frontend/src/bundles/common/components/input/input.tsx +++ b/frontend/src/bundles/common/components/input/input.tsx @@ -14,7 +14,7 @@ import { import { useFormField } from '~/bundles/common/hooks/hooks.js'; type Properties = { - label: string; + label?: string; name: FieldInputProps['name']; type?: 'text' | 'email' | 'number' | 'password'; isRequired?: boolean; diff --git a/frontend/src/bundles/common/components/select/select.tsx b/frontend/src/bundles/common/components/select/select.tsx index 20cce289c..a0114ffdf 100644 --- a/frontend/src/bundles/common/components/select/select.tsx +++ b/frontend/src/bundles/common/components/select/select.tsx @@ -13,7 +13,7 @@ import { import { useFormField } from '~/bundles/common/hooks/hooks.js'; type Properties = { - label: string; + label?: string; name: FieldInputProps['name']; children: React.ReactNode; isRequired?: boolean; @@ -31,7 +31,7 @@ const Select: React.FC> = ({ return ( - {label} + {label && {label}} = ({ children }) => { label="My Avatar" /> + + + } + isCollapsed={isCollapsed} + label="Templates" + /> + = { initialValues: T; mode?: ValueOf; validationSchema?: ValidationSchema; - onSubmit: FormConfig['onSubmit']; + onSubmit?: FormConfig['onSubmit']; }; type ReturnValue = ReturnType< @@ -32,7 +32,9 @@ const useAppForm = ({ initialValues, mode = 'onSubmit', validationSchema, - onSubmit, + onSubmit = (values: T): void => { + values; + }, }: Parameters): ReturnValue => { const validateOnBlur = mode === ValidationMode.ALL ? true : mode === ValidationMode.ON_BLUR; diff --git a/frontend/src/bundles/common/icons/helper/icon-conversion.helper.ts b/frontend/src/bundles/common/icons/helper/icon-conversion.helper.ts index 8d5c65d5d..75d8c3b94 100644 --- a/frontend/src/bundles/common/icons/helper/icon-conversion.helper.ts +++ b/frontend/src/bundles/common/icons/helper/icon-conversion.helper.ts @@ -10,6 +10,7 @@ import { faForwardStep, faHouse, faImage, + faMagnifyingGlass, faPause, faPen, faPlay, @@ -47,6 +48,7 @@ const Stop = convertIcon(faStop); const VideoCamera = convertIcon(faVideoCamera); const Image = convertIcon(faImage); const Circle = convertIcon(faCircle); +const Magnifying = convertIcon(faMagnifyingGlass); export { BackwardStep, @@ -60,6 +62,7 @@ export { ForwardStep, House, Image, + Magnifying, Pause, Pen, Play, diff --git a/frontend/src/bundles/common/icons/icon-name.ts b/frontend/src/bundles/common/icons/icon-name.ts index d18d9936f..644059bf9 100644 --- a/frontend/src/bundles/common/icons/icon-name.ts +++ b/frontend/src/bundles/common/icons/icon-name.ts @@ -26,6 +26,7 @@ import { ForwardStep, House, Image, + Magnifying, Pause, Pen, Play, @@ -77,6 +78,7 @@ const IconName = { IMAGE: Image, CIRCLE: Circle, ARROW_BACK: ArrowBackIcon, + MAGNIFYING: Magnifying, } as const; export { IconName }; diff --git a/frontend/src/bundles/template/components/components.ts b/frontend/src/bundles/template/components/components.ts new file mode 100644 index 000000000..7b03e2032 --- /dev/null +++ b/frontend/src/bundles/template/components/components.ts @@ -0,0 +1,2 @@ +export { CreationsSection } from './creations-section/creations-section.js'; +export { TemplatesSection } from './templates-section/templates-section.js'; diff --git a/frontend/src/bundles/template/components/creations-section/creations-section.tsx b/frontend/src/bundles/template/components/creations-section/creations-section.tsx new file mode 100644 index 000000000..8c71bb984 --- /dev/null +++ b/frontend/src/bundles/template/components/creations-section/creations-section.tsx @@ -0,0 +1,67 @@ +import { + Box, + Button, + Flex, + Heading, +} from '~/bundles/common/components/components.js'; +import { Circles, Dots } from '~/bundles/my-avatar/components/components.js'; +import { type Template } from '~/bundles/template/types/types.js'; + +import { TemplateCard } from '../template-card/template-card.js'; +import styles from './styles.module.css'; + +//TODO: Change with the backend information +const templates: Template[] = []; + +type Properties = { + onClick: () => void; +}; + +const CreationsSection: React.FC = ({ onClick }) => { + return ( + + + + Recent Creations + + + + {templates.length > 0 ? ( + + {templates.map(({ id, ...template }) => ( + + + + ))} + + ) : ( + + + + + + + + + + + {templates.map(({ id, ...template }) => ( + + ))} + + + ); +}; + +export { TemplatesSection }; diff --git a/frontend/src/bundles/template/pages/styles.module.css b/frontend/src/bundles/template/pages/styles.module.css new file mode 100644 index 000000000..a781376f5 --- /dev/null +++ b/frontend/src/bundles/template/pages/styles.module.css @@ -0,0 +1,8 @@ +.container { + height: calc(100vh - 75px); + padding: 25px; + flex-direction: column; + overflow: auto; + scrollbar-width: thin; + clip-path: inset(0 round 0 0.75rem 0 0); +} diff --git a/frontend/src/bundles/template/pages/templates.tsx b/frontend/src/bundles/template/pages/templates.tsx new file mode 100644 index 000000000..9e326cb35 --- /dev/null +++ b/frontend/src/bundles/template/pages/templates.tsx @@ -0,0 +1,68 @@ +import { + Box, + Button, + Flex, + Header, + Icon, + Sidebar, + Text, +} from '~/bundles/common/components/components.js'; +import { useCollapse } from '~/bundles/common/components/sidebar/hooks/use-collapse.hook.js'; +import { AppRoute } from '~/bundles/common/enums/enums.js'; +import { useCallback, useNavigate } from '~/bundles/common/hooks/hooks.js'; +import { IconName } from '~/bundles/common/icons/icons.js'; +import { + CreationsSection, + TemplatesSection, +} from '~/bundles/template/components/components.js'; + +import styles from './styles.module.css'; + +const Templates: React.FC = () => { + const { isCollapsed } = useCollapse(); + + const navigate = useNavigate(); + + const handleClick = useCallback(() => { + navigate(AppRoute.STUDIO); + }, [navigate]); + + return ( + +
+ + + + + Templates + + + + + + + + + + ); +}; + +export { Templates }; diff --git a/frontend/src/bundles/template/types/template.type.ts b/frontend/src/bundles/template/types/template.type.ts new file mode 100644 index 000000000..5bf45cdc3 --- /dev/null +++ b/frontend/src/bundles/template/types/template.type.ts @@ -0,0 +1,8 @@ +type Template = { + id: string; + name: string; + url: string | null; + previewUrl: string; +}; + +export { type Template }; diff --git a/frontend/src/bundles/template/types/types.ts b/frontend/src/bundles/template/types/types.ts new file mode 100644 index 000000000..58b953e07 --- /dev/null +++ b/frontend/src/bundles/template/types/types.ts @@ -0,0 +1 @@ +export { type Template } from './template.type.js'; diff --git a/frontend/src/routes/routes.tsx b/frontend/src/routes/routes.tsx index 1a6e2e18d..6db4541bb 100644 --- a/frontend/src/routes/routes.tsx +++ b/frontend/src/routes/routes.tsx @@ -7,6 +7,7 @@ import { CreateAvatar } from '~/bundles/create-avatar/pages/create-avatar.js'; import { Home } from '~/bundles/home/pages/home.js'; import { MyAvatar } from '~/bundles/my-avatar/pages/my-avatar.js'; import { Studio } from '~/bundles/studio/pages/studio.js'; +import { Templates } from '~/bundles/template/pages/templates.js'; const routes = [ { @@ -53,6 +54,14 @@ const routes = [ ), }, + { + path: AppRoute.TEMPLATES, + element: ( + + + + ), + }, { path: AppRoute.ANY, element: ,