diff --git a/public/images/document.png b/public/images/document.png new file mode 100644 index 0000000..3a35e1e Binary files /dev/null and b/public/images/document.png differ diff --git a/public/images/weight.png b/public/images/weight.png new file mode 100644 index 0000000..e120377 Binary files /dev/null and b/public/images/weight.png differ diff --git a/src/shared/styles/custom.scss b/src/shared/styles/custom.scss index 1f54f9c..13e08a6 100644 --- a/src/shared/styles/custom.scss +++ b/src/shared/styles/custom.scss @@ -1,5 +1,3 @@ -@use "@/shared/ui/Modal/ui/Modal/modal.global"; - path { transition: 0.2s d ease-in-out; } diff --git a/src/shared/ui/Empty/Empty.tsx b/src/shared/ui/Empty/Empty.tsx new file mode 100644 index 0000000..7bbf1f3 --- /dev/null +++ b/src/shared/ui/Empty/Empty.tsx @@ -0,0 +1,46 @@ +import Image from 'next/image'; + +import { Flex } from '../Flex'; +import { Text } from '../Text'; + +import styles from './empty.module.scss'; + +interface IEmpty { + description?: string + icon?: React.ReactNode + title?: string +} + +export const Empty = ({ + description, + icon = ( + <Image + alt="empty" + height={512} + src="/images/document.png" + width={512} + /> + ), + title = 'Ничего не найдено...', +}: IEmpty) => ( + <Flex + align="center" + className={styles.wrapper} + full={true} + gap={8} + justify="center" + vertical={true} + > + <div className={styles.icon}> + {icon} + </div> + <Flex align="center" vertical={true}> + <Text align="text-center" color="text-base-400" size="text-sm"> + {title} + </Text> + <Text align="text-center" color="text-base-600" size={0.7}> + {description} + </Text> + </Flex> + </Flex> +); diff --git a/src/shared/ui/Empty/empty.module.scss b/src/shared/ui/Empty/empty.module.scss new file mode 100644 index 0000000..f99b02d --- /dev/null +++ b/src/shared/ui/Empty/empty.module.scss @@ -0,0 +1,11 @@ +.wrapper { + height: 100%; + max-height: calc(100vh - 100px); +} + +.icon { + max-width: 64px; + max-height: 64px; + pointer-events: none; + user-select: none; +} \ No newline at end of file diff --git a/src/shared/ui/Empty/index.ts b/src/shared/ui/Empty/index.ts new file mode 100644 index 0000000..936ad1e --- /dev/null +++ b/src/shared/ui/Empty/index.ts @@ -0,0 +1 @@ +export { Empty } from './Empty'; diff --git a/src/shared/ui/Modal/ui/Modal/Modal.tsx b/src/shared/ui/Modal/ui/Modal/Modal.tsx index ef7aa5a..2faa122 100644 --- a/src/shared/ui/Modal/ui/Modal/Modal.tsx +++ b/src/shared/ui/Modal/ui/Modal/Modal.tsx @@ -8,6 +8,7 @@ import { isClient } from '@/shared/lib/next'; import { Flex } from '@/shared/ui'; import styles from './modal.module.scss'; +import './modal.global.scss'; export interface IModal { button: React.ReactElement<{ onClick?: () => void }> diff --git a/src/shared/ui/index.ts b/src/shared/ui/index.ts index b978add..0d0f1da 100644 --- a/src/shared/ui/index.ts +++ b/src/shared/ui/index.ts @@ -2,6 +2,7 @@ export * from './Background'; export * from './Button'; export * from './Chip'; export * from './Divider'; +export * from './Empty'; export * from './Flex'; export * from './Header'; export * from './Icon'; diff --git a/src/widgets/AddExerciseModal/model/mock.ts b/src/widgets/AddExerciseModal/model/mock.ts index 479c2df..9f40b4f 100644 --- a/src/widgets/AddExerciseModal/model/mock.ts +++ b/src/widgets/AddExerciseModal/model/mock.ts @@ -23,7 +23,7 @@ export const mockAddExerciseModal: IGroupExercises[] = [ }, { color: '#9B693B', - exercises: ['1', '2', '3', '4'], + exercises: [], name: 'Квадрицепсы', }, ]; diff --git a/src/widgets/AddExerciseModal/ui/AddExerciseModal.tsx b/src/widgets/AddExerciseModal/ui/AddExerciseModal.tsx index 1bcdfd8..b685d00 100644 --- a/src/widgets/AddExerciseModal/ui/AddExerciseModal.tsx +++ b/src/widgets/AddExerciseModal/ui/AddExerciseModal.tsx @@ -1,10 +1,11 @@ 'use client'; import { clsx } from 'clsx'; +import Image from 'next/image'; import { useState } from 'react'; import { AddOutlineIcon, SettingsOutlineIcon } from '@/shared/icons'; -import { Button, Flex, Text, Background, Input, ModalBase, Chip } from '@/shared/ui'; +import { Button, Flex, Text, Background, Input, ModalBase, Chip, Empty } from '@/shared/ui'; import styles from './addExerciseModal.module.scss'; @@ -55,72 +56,88 @@ export const AddExerciseModal = ({ items }: IAddExerciseModal) => { )} > <Flex className={styles.wrapper} gap="medium" vertical={true}> - {selectedGroup - ? ( - <Flex className={styles.groupWrapper} gap={10} vertical={true}> - <Background className={clsx(styles.group, styles.visible)}> - {selectedGroup.exercises.map((item, index) => ( - <Button - align="start" - className={styles.item} - full={true} - isActiveAnimation={false} - key={item} - radius="none" - variant="none" - > - <Text className={styles.index} color="text-base-600" size={0.7}> - {`${index + 1}.`} - </Text> - <Chip> - <Text customColor={selectedGroup.color}> - {selectedGroup.name} + {selectedGroup ? ( + <Flex className={styles.groupWrapper} gap={10} vertical={true}> + <Background className={clsx(styles.group, styles.visible)}> + {selectedGroup.exercises.length > 0 ? ( + <> + {selectedGroup.exercises.map((item, index) => ( + <Button + align="start" + className={styles.item} + full={true} + isActiveAnimation={false} + key={item} + radius="none" + variant="none" + > + <Text className={styles.index} color="text-base-600" size={0.7}> + {`${index + 1}.`} + </Text> + <Chip> + <Text customColor={selectedGroup.color}> + {selectedGroup.name} + </Text> + </Chip> + <Text size="text-sm" weight="font-light"> + {item} </Text> - </Chip> - <Text size="text-sm" weight="font-light"> - {item} - </Text> - </Button> - ))} - <Text - align="text-center" - className={styles.end} - color="text-base-700" - size="text-sm" - > - Это конец списка - </Text> - </Background> - <Input - className={styles.visible} - rightAction={( - <Button className={styles.buttonAdd} size="large" variant="solid"> - Добавить - </Button> - )} - /> - </Flex> - ) - : items.map((item) => ( - <Button - className={clsx(styles.button, styles.visible)} - full={true} - key={item.name} - onClick={() => setSelectedGroup(item)} - variant="none" + </Button> + ))} + <Text + align="text-center" + className={styles.end} + color="text-base-700" + size="text-sm" + > + Это конец списка + </Text> + </> + ) : ( + <Empty + description="Добавьте первое упражнение!" + icon={( + <Image + alt="empty" + height={512} + src="/images/weight.png" + width={512} + /> + )} + title="Здесь пока нет упражнений..." + /> + )} + </Background> + <Input + className={styles.visible} + placeholder="Название упражнения" + rightAction={( + <Button className={styles.buttonAdd} size="large" variant="solid"> + Добавить + </Button> + )} + /> + </Flex> + ) : items.map((item) => ( + <Button + className={clsx(styles.button, styles.visible)} + full={true} + key={item.name} + onClick={() => setSelectedGroup(item)} + variant="none" + > + <span className={styles.light} style={{ backgroundColor: item.color }} /> + <Text className={styles.name} customColor={item.color}> + {item.name} + </Text> + <Text + color="text-base-700" + size="text-sm" > - <span className={styles.light} style={{ backgroundColor: item.color }} /> - <Text className={styles.name} customColor={item.color}> - {item.name} - </Text> - <Text - color="text-base-700" - size="text-sm" - > - {getCountExerciseWord(item.exercises.length)} - </Text> - </Button> - ))} + {getCountExerciseWord(item.exercises.length)} + </Text> + </Button> + ))} </Flex> </ModalBase> );