Skip to content

Commit 328abdc

Browse files
committed
refactor: integrate EntityCardShared component in various dashboard widgets and remove unused styles
1 parent b7a0bde commit 328abdc

File tree

23 files changed

+779
-1737
lines changed

23 files changed

+779
-1737
lines changed

src/pages/dashboard/subpage-config/ui/components/subpage-config-editor-page.component.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,7 @@ export const SubpageConfigEditorPageComponent = (props: Props) => {
218218
</ActionIcon>
219219
</Group>
220220
}
221+
description={config.uuid}
221222
icon={<TbFile size={24} />}
222223
title={config.name}
223224
/>
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import { Group } from '@mantine/core'
2+
3+
interface ActionsProps {
4+
children: React.ReactNode
5+
}
6+
7+
export function EntityCardActions({ children }: ActionsProps) {
8+
return (
9+
<Group gap={0} wrap="nowrap">
10+
{children}
11+
</Group>
12+
)
13+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import { Button } from '@mantine/core'
2+
3+
import classes from './entity-card.module.css'
4+
5+
interface ButtonActionProps {
6+
children: React.ReactNode
7+
color?: string
8+
leftSection?: React.ReactNode
9+
onClick?: (e: React.MouseEvent) => void
10+
}
11+
12+
export function EntityCardButtonAction({
13+
children,
14+
leftSection,
15+
onClick,
16+
color = 'cyan'
17+
}: ButtonActionProps) {
18+
return (
19+
<Button
20+
className={classes.button}
21+
color={color}
22+
fullWidth
23+
leftSection={leftSection}
24+
onClick={(e) => {
25+
e.stopPropagation()
26+
onClick?.(e)
27+
}}
28+
size="sm"
29+
variant="light"
30+
>
31+
{children}
32+
</Button>
33+
)
34+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import { Stack, Text } from '@mantine/core'
2+
3+
import classes from './entity-card.module.css'
4+
5+
interface ContentProps {
6+
children?: React.ReactNode
7+
subtitle?: string
8+
title: string
9+
}
10+
11+
export function EntityCardContent({ children, title, subtitle }: ContentProps) {
12+
return (
13+
<Stack gap={6} style={{ flex: 1, minWidth: 0 }}>
14+
<Text
15+
className={classes.title}
16+
ff="monospace"
17+
fw={700}
18+
lineClamp={1}
19+
size="lg"
20+
title={title}
21+
>
22+
{title}
23+
</Text>
24+
{subtitle && (
25+
<Text c="dimmed" className={classes.subtitle} lineClamp={1} size="xs">
26+
{subtitle}
27+
</Text>
28+
)}
29+
{children}
30+
</Stack>
31+
)
32+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import { createContext, useContext } from 'react'
2+
3+
interface EntityCardContextValue {
4+
menuOpened: boolean
5+
setMenuOpened: (opened: boolean) => void
6+
}
7+
8+
export const EntityCardContext = createContext<EntityCardContextValue | null>(null)
9+
10+
export const useEntityCardContext = () => {
11+
const context = useContext(EntityCardContext)
12+
if (!context) {
13+
throw new Error('EntityCard components must be used within EntityCard')
14+
}
15+
return context
16+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import { Group, Stack } from '@mantine/core'
2+
3+
interface HeaderProps {
4+
children: React.ReactNode
5+
}
6+
7+
export function EntityCardHeader({ children }: HeaderProps) {
8+
return (
9+
<Stack gap="md">
10+
<Group gap="md" wrap="nowrap">
11+
{children}
12+
</Group>
13+
</Stack>
14+
)
15+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import { ActionIcon, ActionIconProps, Box, PolymorphicComponentProps } from '@mantine/core'
2+
3+
import classes from './entity-card.module.css'
4+
5+
interface EntityCardIconProps extends PolymorphicComponentProps<'button', ActionIconProps> {
6+
highlight?: boolean
7+
}
8+
9+
export function EntityCardIcon({ children, highlight = true, ...props }: EntityCardIconProps) {
10+
return (
11+
<Box className={classes.iconWrapper}>
12+
<ActionIcon
13+
className={classes.icon}
14+
color={highlight ? 'teal' : 'cyan'}
15+
size="xl"
16+
variant="light"
17+
{...props}
18+
>
19+
{children}
20+
</ActionIcon>
21+
</Box>
22+
)
23+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import { useDisclosure, useId } from '@mantine/hooks'
2+
import { ActionIcon, Menu } from '@mantine/core'
3+
import { TbChevronDown } from 'react-icons/tb'
4+
import clsx from 'clsx'
5+
6+
// import { useEntityCardContext } from './entity-card.context'
7+
import classes from './entity-card.module.css'
8+
9+
interface MenuActionProps {
10+
children: React.ReactNode
11+
color?: string
12+
}
13+
14+
export function EntityCardMenuAction({ children, color = 'cyan' }: MenuActionProps) {
15+
const uuid = useId()
16+
// const { menuOpened, setMenuOpened } = useEntityCardContext()
17+
const [opened, handlers] = useDisclosure()
18+
19+
return (
20+
<Menu
21+
key={uuid}
22+
onClose={handlers.close}
23+
onOpen={handlers.open}
24+
position="bottom-end"
25+
radius="md"
26+
trigger="click-hover"
27+
withinPortal
28+
>
29+
<Menu.Target>
30+
<ActionIcon className={classes.menuControl} color={color} size="36" variant="light">
31+
<TbChevronDown
32+
className={clsx(classes.menuControlIcon, {
33+
[classes.menuControlIconOpen]: opened,
34+
[classes.menuControlIconClosed]: !opened
35+
})}
36+
size={20}
37+
/>
38+
</ActionIcon>
39+
</Menu.Target>
40+
41+
<Menu.Dropdown>{children}</Menu.Dropdown>
42+
</Menu>
43+
)
44+
}

src/widgets/dashboard/internal-squads/internal-squad-card/internal-squad-card.module.css renamed to src/shared/ui/entity-card/entity-card.module.css

File renamed without changes.
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import { Box, Card, Stack } from '@mantine/core'
2+
import { useState } from 'react'
3+
import clsx from 'clsx'
4+
5+
import { EntityCardContext } from './entity-card.context'
6+
import classes from './entity-card.module.css'
7+
8+
interface EntityCardProps {
9+
children: React.ReactNode
10+
withTopAccent?: boolean
11+
}
12+
13+
export function EntityCardRoot({ children, withTopAccent = true }: EntityCardProps) {
14+
const [menuOpened, setMenuOpened] = useState(false)
15+
16+
return (
17+
<EntityCardContext.Provider value={{ menuOpened, setMenuOpened }}>
18+
<Card className={classes.card} h="100%" p="xl" shadow="sm" withBorder>
19+
<Box
20+
className={clsx({
21+
[classes.topAccent]: withTopAccent,
22+
[classes.inactiveTopAccent]: !withTopAccent
23+
})}
24+
/>
25+
26+
<Box className={classes.glowEffect} />
27+
28+
<Stack gap="lg" justify="space-between" style={{ flex: 1 }}>
29+
{children}
30+
</Stack>
31+
</Card>
32+
</EntityCardContext.Provider>
33+
)
34+
}

0 commit comments

Comments
 (0)