Merge pull request #44 from twentyhq/sammy/t-102-i-see-people-chip-designed-with-picture

Sammy/t 102 i see people chip designed with picture
This commit is contained in:
Sammy Teillet
2023-04-19 14:38:41 +02:00
committed by GitHub
9 changed files with 181 additions and 32 deletions

View File

@ -1,11 +1,9 @@
import * as React from 'react';
import styled from '@emotion/styled';
import { Link } from 'react-router-dom';
type OwnProps = {
name: string;
picture?: string;
href: string;
};
const StyledContainer = styled.span`
@ -28,15 +26,19 @@ const StyledContainer = styled.span`
}
`;
function CellLink({ name, picture, href }: OwnProps) {
function CompanyChip({ name, picture }: OwnProps) {
return (
<Link to={href}>
<StyledContainer>
{picture && <img src={picture?.toString()} alt="" />}
{name}
</StyledContainer>
</Link>
<StyledContainer data-testid="company-chip">
{picture && (
<img
data-testid="company-chip-image"
src={picture?.toString()}
alt={`${name}-company-logo`}
/>
)}
{name}
</StyledContainer>
);
}
export default CellLink;
export default CompanyChip;

View File

@ -0,0 +1,44 @@
import * as React from 'react';
import styled from '@emotion/styled';
import PersonPlaceholder from './person-placeholder.png';
type OwnProps = {
name: string;
picture?: string;
};
const StyledContainer = styled.span`
background-color: ${(props) => props.theme.tertiaryBackground};
border-radius: ${(props) => props.theme.spacing(1)};
color: ${(props) => props.theme.text80};
display: inline-flex;
align-items: center;
padding: ${(props) => props.theme.spacing(1)};
gap: ${(props) => props.theme.spacing(1)};
:hover {
filter: brightness(95%);
}
img {
height: 14px;
width: 14px;
border-radius: 100%;
object-fit: cover;
}
`;
function PersonChip({ name, picture }: OwnProps) {
return (
<StyledContainer data-testid="person-chip">
<img
data-testid="person-chip-image"
src={picture ? picture.toString() : PersonPlaceholder.toString()}
alt="person-picture"
/>
{name}
</StyledContainer>
);
}
export default PersonChip;

View File

@ -0,0 +1,24 @@
import CompanyChip from '../CompanyChip';
import { ThemeProvider } from '@emotion/react';
import { lightTheme } from '../../../layout/styles/themes';
export default {
title: 'CompanyChip',
component: CompanyChip,
};
export const RegularCompanyChip = () => {
return (
<ThemeProvider theme={lightTheme}>
<CompanyChip name="selected-company-1" />
</ThemeProvider>
);
};
export const RegularCompanyChipWithImage = () => {
return (
<ThemeProvider theme={lightTheme}>
<CompanyChip name="selected-company-1" picture="coucou.fr" />
</ThemeProvider>
);
};

View File

@ -0,0 +1,24 @@
import { ThemeProvider } from '@emotion/react';
import { lightTheme } from '../../../layout/styles/themes';
import PersonChip from '../PersonChip';
export default {
title: 'PersonChip',
component: PersonChip,
};
export const RegularPersonChip = () => {
return (
<ThemeProvider theme={lightTheme}>
<PersonChip name="selected-company-1" />
</ThemeProvider>
);
};
export const RegularPersonChipWithImage = () => {
return (
<ThemeProvider theme={lightTheme}>
<PersonChip name="selected-company-1" picture="coucou.fr" />
</ThemeProvider>
);
};

View File

@ -0,0 +1,18 @@
import { render } from '@testing-library/react';
import {
RegularCompanyChip,
RegularCompanyChipWithImage,
} from '../__stories__/CompanyChip';
it('Checks the CompanyChip renders', () => {
const { getByText } = render(<RegularCompanyChip />);
expect(getByText('selected-company-1')).toBeDefined();
});
it('Checks the CompanyChip img renders', () => {
const { getByTestId } = render(<RegularCompanyChipWithImage />);
expect(getByTestId('company-chip-image')).toHaveAttribute('src', 'coucou.fr');
});

View File

@ -0,0 +1,22 @@
import { render } from '@testing-library/react';
import {
RegularPersonChip,
RegularPersonChipWithImage,
} from '../__stories__/PersonChip';
it('Checks the PersonChip renders', () => {
const { getByText, getByTestId } = render(<RegularPersonChip />);
expect(getByText('selected-company-1')).toBeDefined();
expect(getByTestId('person-chip-image')).toHaveAttribute(
'src',
'person-placeholder.png',
);
});
it('Checks the PersonChip img renders', () => {
const { getByTestId } = render(<RegularPersonChipWithImage />);
expect(getByTestId('person-chip-image')).toHaveAttribute('src', 'coucou.fr');
});

View File

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

View File

@ -0,0 +1,13 @@
import * as React from 'react';
import { Link } from 'react-router-dom';
type OwnProps = {
href: string;
children?: React.ReactNode;
};
function ClickableCell({ href, children }: OwnProps) {
return <Link to={href}>{children}</Link>;
}
export default ClickableCell;

View File

@ -12,12 +12,13 @@ import { Company } from '../../interfaces/company.interface';
import { Pipe } from '../../interfaces/pipe.interface';
import { createColumnHelper } from '@tanstack/react-table';
import styled from '@emotion/styled';
import CellLink from '../../components/table/CellLink';
import ClickableCell from '../../components/table/ClickableCell';
import ColumnHead from '../../components/table/ColumnHead';
import personPlaceholder from './placeholder.png';
import { parsePhoneNumber, CountryCode } from 'libphonenumber-js';
import Checkbox from '../../components/form/Checkbox';
import HorizontalyAlignedContainer from '../../layout/containers/HorizontalyAlignedContainer';
import CompanyChip from '../../components/chips/CompanyChip';
import PersonChip from '../../components/chips/PersonChip';
type Person = {
fullName: string;
@ -46,7 +47,7 @@ const StyledPeopleContainer = styled.div`
const defaultData: Array<Person> = [
{
fullName: 'Alexandre Prot',
picture: personPlaceholder,
picture: 'http://placekitten.com/256',
email: 'alexandre@qonto.com',
company: { id: 1, name: 'Qonto', domain: 'qonto.com' },
phone: '06 12 34 56 78',
@ -57,7 +58,6 @@ const defaultData: Array<Person> = [
},
{
fullName: 'Alexandre Prot',
picture: personPlaceholder,
email: 'alexandre@qonto.com',
company: { id: 2, name: 'LinkedIn', domain: 'linkedin.com' },
phone: '06 12 34 56 78',
@ -68,7 +68,7 @@ const defaultData: Array<Person> = [
},
{
fullName: 'Alexandre Prot',
picture: personPlaceholder,
picture: 'http://placekitten.com/256',
email: 'alexandre@qonto.com',
company: { id: 1, name: 'Qonto', domain: 'qonto.com' },
phone: '06 12 34 56 78',
@ -79,7 +79,7 @@ const defaultData: Array<Person> = [
},
{
fullName: 'Alexandre Prot',
picture: personPlaceholder,
picture: 'https://placekitten.com/g/256',
email: 'alexandre@qonto.com',
company: { id: 1, name: 'Slack', domain: 'slack.com' },
phone: '06 12 34 56 78',
@ -90,7 +90,6 @@ const defaultData: Array<Person> = [
},
{
fullName: 'Alexandre Prot',
picture: personPlaceholder,
email: 'alexandre@qonto.com',
company: { id: 2, name: 'Facebook', domain: 'facebook.com' },
phone: '06 12 34 56 78',
@ -112,11 +111,12 @@ const columns = [
id={`person-selected-${props.row.original.email}`}
name={`person-selected${props.row.original.email}`}
/>
<CellLink
name={props.row.original.fullName}
picture={props.row.original.picture}
href="#"
/>
<ClickableCell href="#">
<PersonChip
name={props.row.original.fullName}
picture={props.row.original.picture}
/>
</ClickableCell>
</HorizontalyAlignedContainer>
),
}),
@ -131,11 +131,12 @@ const columns = [
columnHelper.accessor('company', {
header: () => <ColumnHead viewName="Company" viewIcon={faBuildings} />,
cell: (props) => (
<CellLink
name={props.row.original.company.name}
picture={`https://www.google.com/s2/favicons?domain=${props.row.original.company.domain}&sz=256`}
href="#"
/>
<ClickableCell href="#">
<CompanyChip
name={props.row.original.company.name}
picture={`https://www.google.com/s2/favicons?domain=${props.row.original.company.domain}&sz=256`}
/>
</ClickableCell>
),
}),
columnHelper.accessor('phone', {
@ -166,11 +167,12 @@ const columns = [
columnHelper.accessor('pipe', {
header: () => <ColumnHead viewName="Pipe" viewIcon={faRectangleList} />,
cell: (props) => (
<CellLink
name={props.row.original.pipe.name}
picture={props.row.original.pipe.icon}
href="#"
/>
<ClickableCell href="#">
<CompanyChip
name={props.row.original.pipe.name}
picture={props.row.original.pipe.icon}
/>
</ClickableCell>
),
}),
columnHelper.accessor('city', {