Merge pull request #179 from Compagnia-d-Arme-del-Santo-Luca/refactor/people/info-icon-on-card
♻️ refactor(people): add info icon to employee card
This commit is contained in:
@@ -4,7 +4,7 @@ name: Deployment (Staging)
|
|||||||
on:
|
on:
|
||||||
# Runs on pushes targeting the default branch
|
# Runs on pushes targeting the default branch
|
||||||
push:
|
push:
|
||||||
branches: ["main"]
|
branches: ['main']
|
||||||
|
|
||||||
# Allows you to run this workflow manually from the Actions tab
|
# Allows you to run this workflow manually from the Actions tab
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
@@ -20,8 +20,8 @@ jobs:
|
|||||||
- name: Set up Node
|
- name: Set up Node
|
||||||
uses: actions/setup-node@v6
|
uses: actions/setup-node@v6
|
||||||
with:
|
with:
|
||||||
node-version: "lts/*"
|
node-version: 'lts/*'
|
||||||
cache: "npm"
|
cache: 'npm'
|
||||||
|
|
||||||
- name: Set environment variables
|
- name: Set environment variables
|
||||||
run: |
|
run: |
|
||||||
@@ -32,8 +32,8 @@ jobs:
|
|||||||
if [[ -n "${{ vars.VITE_BC_POSITION }}" ]]; then
|
if [[ -n "${{ vars.VITE_BC_POSITION }}" ]]; then
|
||||||
echo "VITE_BC_POSITION=${{ vars.VITE_BC_POSITION }}" >> .env
|
echo "VITE_BC_POSITION=${{ vars.VITE_BC_POSITION }}" >> .env
|
||||||
fi
|
fi
|
||||||
if [[ -n "${{ vars.VITE_BC_VAT }}" ]]; then
|
if [[ -n "${{ vars.VITE_BC_INSTAGRAM }}" ]]; then
|
||||||
echo "VITE_BC_VAT=${{ vars.VITE_BC_VAT }}" >> .env
|
echo "VITE_BC_INSTAGRAM=${{ vars.VITE_BC_INSTAGRAM }}" >> .env
|
||||||
fi
|
fi
|
||||||
if [[ -n "${{ vars.VITE_BC_FACEBOOK }}" ]]; then
|
if [[ -n "${{ vars.VITE_BC_FACEBOOK }}" ]]; then
|
||||||
echo "VITE_BC_FACEBOOK=${{ vars.VITE_BC_FACEBOOK }}" >> .env
|
echo "VITE_BC_FACEBOOK=${{ vars.VITE_BC_FACEBOOK }}" >> .env
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { render, screen, fireEvent } from '@testing-library/react'
|
import { render, screen, fireEvent } from '@testing-library/react'
|
||||||
import { vi } from 'vitest'
|
import { vi } from 'vitest'
|
||||||
|
|
||||||
import EmplyeeCard from './index'
|
import EmployeeCard from './index'
|
||||||
|
|
||||||
describe('EmplyeeCard', () => {
|
describe('EmplyeeCard', () => {
|
||||||
const name = 'John Doe'
|
const name = 'John Doe'
|
||||||
@@ -9,7 +9,7 @@ describe('EmplyeeCard', () => {
|
|||||||
const position = 'Blacksmith'
|
const position = 'Blacksmith'
|
||||||
|
|
||||||
it('renders name, image and optional position', () => {
|
it('renders name, image and optional position', () => {
|
||||||
render(<EmplyeeCard name={name} image={image} position={position} />)
|
render(<EmployeeCard name={name} image={image} position={position} />)
|
||||||
|
|
||||||
expect(screen.getByText(name)).toBeInTheDocument()
|
expect(screen.getByText(name)).toBeInTheDocument()
|
||||||
expect(screen.getByText(position)).toBeInTheDocument()
|
expect(screen.getByText(position)).toBeInTheDocument()
|
||||||
@@ -22,7 +22,7 @@ describe('EmplyeeCard', () => {
|
|||||||
it('calls onClick with (event, description) payload', () => {
|
it('calls onClick with (event, description) payload', () => {
|
||||||
const description = { body: ['this is a description for John Doe'] }
|
const description = { body: ['this is a description for John Doe'] }
|
||||||
const handleClick = vi.fn()
|
const handleClick = vi.fn()
|
||||||
render(<EmplyeeCard name={name} image={image} position={position} description={description} onClick={handleClick} />)
|
render(<EmployeeCard name={name} image={image} position={position} description={description} onClick={handleClick} />)
|
||||||
|
|
||||||
fireEvent.click(screen.getByText(name))
|
fireEvent.click(screen.getByText(name))
|
||||||
|
|
||||||
@@ -43,7 +43,7 @@ describe('EmplyeeCard', () => {
|
|||||||
body: ['this is a description for Jane Doe'],
|
body: ['this is a description for Jane Doe'],
|
||||||
}
|
}
|
||||||
const handleClick = vi.fn()
|
const handleClick = vi.fn()
|
||||||
render(<EmplyeeCard name={name} image={image} position={position} description={description} onClick={handleClick} />)
|
render(<EmployeeCard name={name} image={image} position={position} description={description} onClick={handleClick} />)
|
||||||
|
|
||||||
fireEvent.click(screen.getByText(name))
|
fireEvent.click(screen.getByText(name))
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { FC, useMemo } from 'react'
|
import { FC, useMemo } from 'react'
|
||||||
import { Card, CardActionArea, CardContent, CardMedia, CardProps, Typography } from '@mui/material'
|
import { Card, CardActionArea, CardContent, CardMedia, CardProps, Typography } from '@mui/material'
|
||||||
|
import InfoOutline from '@mui/icons-material/InfoOutline'
|
||||||
|
|
||||||
import { EmployeeDescription } from 'components/molecules/EmployeeDescription/index.js'
|
import { EmployeeDescription } from 'components/molecules/EmployeeDescription/index.js'
|
||||||
|
|
||||||
@@ -11,9 +12,9 @@ export type EmployeeCardProps = Omit<CardProps, 'onClick'> & {
|
|||||||
onClick?: (event: React.MouseEvent<HTMLDivElement, MouseEvent>, description: EmployeeDescription) => void
|
onClick?: (event: React.MouseEvent<HTMLDivElement, MouseEvent>, description: EmployeeDescription) => void
|
||||||
}
|
}
|
||||||
|
|
||||||
export const EmplyeeCard: FC<EmployeeCardProps> = ({ name, position, image, description = {}, sx, onClick, ...props }) => {
|
export const EmployeeCard: FC<EmployeeCardProps> = ({ name, position, image, description = {}, sx, onClick, ...props }) => {
|
||||||
const handleClick = (event: React.MouseEvent<HTMLDivElement, MouseEvent>) => {
|
const handleClick = (event: React.MouseEvent<HTMLDivElement, MouseEvent>) => {
|
||||||
onClick(event, {
|
onClick?.(event, {
|
||||||
title: name,
|
title: name,
|
||||||
image: image,
|
image: image,
|
||||||
position: position,
|
position: position,
|
||||||
@@ -22,7 +23,7 @@ export const EmplyeeCard: FC<EmployeeCardProps> = ({ name, position, image, desc
|
|||||||
}
|
}
|
||||||
const content = useMemo(
|
const content = useMemo(
|
||||||
() => [
|
() => [
|
||||||
<CardMedia component="img" sx={{ minHeight: '140' }} image={image} alt={`${name} image`} />,
|
<CardMedia component="img" sx={{ minHeight: '140px' }} image={image} alt={`${name} image`} />,
|
||||||
<CardContent>
|
<CardContent>
|
||||||
<Typography gutterBottom variant="h5" component="div">
|
<Typography gutterBottom variant="h5" component="div">
|
||||||
{name}
|
{name}
|
||||||
@@ -32,9 +33,12 @@ export const EmplyeeCard: FC<EmployeeCardProps> = ({ name, position, image, desc
|
|||||||
{position}
|
{position}
|
||||||
</Typography>
|
</Typography>
|
||||||
)}
|
)}
|
||||||
|
{typeof onClick !== 'undefined' && (
|
||||||
|
<InfoOutline fontSize="small" sx={{ color: 'text.disabled', position: 'absolute', bottom: 8, right: 8 }} />
|
||||||
|
)}
|
||||||
</CardContent>,
|
</CardContent>,
|
||||||
],
|
],
|
||||||
[name, position, image]
|
[name, position, image, onClick]
|
||||||
)
|
)
|
||||||
return (
|
return (
|
||||||
<Card sx={{ flexShrink: 0, width: 270, height: 360, ...sx }} {...props} onClick={handleClick}>
|
<Card sx={{ flexShrink: 0, width: 270, height: 360, ...sx }} {...props} onClick={handleClick}>
|
||||||
@@ -43,4 +47,4 @@ export const EmplyeeCard: FC<EmployeeCardProps> = ({ name, position, image, desc
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
export default EmplyeeCard
|
export default EmployeeCard
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import EmplyeeStack from './index'
|
|||||||
// Mock EmplyeeCard to make click handling deterministic in tests
|
// Mock EmplyeeCard to make click handling deterministic in tests
|
||||||
vi.mock('components/molecules/EmplyeeCard/index.js', () => ({
|
vi.mock('components/molecules/EmplyeeCard/index.js', () => ({
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
EmplyeeCard: (props: any) => (
|
EmployeeCard: (props: any) => (
|
||||||
<div
|
<div
|
||||||
data-testid="mock-card"
|
data-testid="mock-card"
|
||||||
onClick={e => props.onClick?.(e, { title: props.name, image: props.image, position: props.position, ...(props.description || {}) })}>
|
onClick={e => props.onClick?.(e, { title: props.name, image: props.image, position: props.position, ...(props.description || {}) })}>
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import { FC, useState } from 'react'
|
|||||||
import { Box, IconButton } from '@mui/material'
|
import { Box, IconButton } from '@mui/material'
|
||||||
import ShuffleIcon from '@mui/icons-material/NextPlan'
|
import ShuffleIcon from '@mui/icons-material/NextPlan'
|
||||||
|
|
||||||
import { EmplyeeCard, EmployeeCardProps } from 'components/molecules/EmplyeeCard/index.js'
|
import { EmployeeCard, EmployeeCardProps } from 'components/molecules/EmplyeeCard/index.js'
|
||||||
import { EmployeeDescription } from 'components/molecules/EmployeeDescription/index.js'
|
import { EmployeeDescription } from 'components/molecules/EmployeeDescription/index.js'
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
@@ -35,7 +35,7 @@ const EmplyeeStack: FC<Props> = ({
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (items.length === 0) return null
|
if (items.length === 0) return null
|
||||||
if (items.length === 1) return <EmplyeeCard {...items[0]} onClick={onClick} />
|
if (items.length === 1) return <EmployeeCard {...items[0]} onClick={onClick} />
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box
|
<Box
|
||||||
@@ -45,7 +45,7 @@ const EmplyeeStack: FC<Props> = ({
|
|||||||
height: 360 + offsetStep * Math.min(initialItems.length - 1, maxVisible),
|
height: 360 + offsetStep * Math.min(initialItems.length - 1, maxVisible),
|
||||||
}}>
|
}}>
|
||||||
{items.slice(0, maxVisible).map((props, idx) => (
|
{items.slice(0, maxVisible).map((props, idx) => (
|
||||||
<EmplyeeCard
|
<EmployeeCard
|
||||||
{...props}
|
{...props}
|
||||||
onClick={onClick}
|
onClick={onClick}
|
||||||
key={idx}
|
key={idx}
|
||||||
|
|||||||
Reference in New Issue
Block a user