diff --git a/front/src/modules/companies/interfaces/__tests__/company.interface.test.ts b/front/src/modules/companies/interfaces/__tests__/company.interface.test.ts
index 4704291bb..0010ffdb4 100644
--- a/front/src/modules/companies/interfaces/__tests__/company.interface.test.ts
+++ b/front/src/modules/companies/interfaces/__tests__/company.interface.test.ts
@@ -33,12 +33,12 @@ describe('Company mappers', () => {
__typename: 'Pipe',
},
],
- __typename: 'companies',
+ __typename: 'Company',
} satisfies GraphqlQueryCompany;
const company = mapToCompany(graphQLCompany);
expect(company).toStrictEqual({
- __typename: 'companies',
+ __typename: 'Company',
id: graphQLCompany.id,
name: graphQLCompany.name,
domainName: graphQLCompany.domainName,
@@ -77,7 +77,7 @@ describe('Company mappers', () => {
__typename: 'users',
},
createdAt: now,
- __typename: 'companies',
+ __typename: 'Company',
} satisfies Company;
const graphQLCompany = mapToGqlCompany(company);
expect(graphQLCompany).toStrictEqual({
@@ -88,7 +88,7 @@ describe('Company mappers', () => {
employees: company.employees,
address: company.address,
accountOwnerId: '522d4ec4-c46b-4360-a0a7-df8df170be81',
- __typename: 'companies',
+ __typename: 'Company',
} satisfies GraphqlMutationCompany);
});
});
diff --git a/front/src/modules/companies/interfaces/company.interface.ts b/front/src/modules/companies/interfaces/company.interface.ts
index 94ade5e4d..e9205aa44 100644
--- a/front/src/modules/companies/interfaces/company.interface.ts
+++ b/front/src/modules/companies/interfaces/company.interface.ts
@@ -9,7 +9,7 @@ import {
} from '../../users/interfaces/user.interface';
export type Company = {
- __typename: 'companies';
+ __typename: 'Company';
id: string;
name?: string;
domainName?: string;
@@ -54,7 +54,7 @@ export type GraphqlMutationCompany = {
};
export const mapToCompany = (company: GraphqlQueryCompany): Company => ({
- __typename: 'companies',
+ __typename: 'Company',
id: company.id,
employees: company.employees,
name: company.name,
@@ -80,5 +80,5 @@ export const mapToGqlCompany = (company: Company): GraphqlMutationCompany => ({
createdAt: company.createdAt ? company.createdAt.toUTCString() : undefined,
accountOwnerId: company.accountOwner?.id,
- __typename: 'companies',
+ __typename: 'Company',
});
diff --git a/front/src/modules/opportunities/components/Board.tsx b/front/src/modules/opportunities/components/Board.tsx
index 2159a8cc5..649e708e7 100644
--- a/front/src/modules/opportunities/components/Board.tsx
+++ b/front/src/modules/opportunities/components/Board.tsx
@@ -61,9 +61,7 @@ export const Board = ({ initialBoard, items }: BoardProps) => {
>
{(draggableProvided) => (
-
- {items[itemKey]?.id || 'Item not found'}
-
+
)}
diff --git a/front/src/modules/opportunities/components/BoardCard.tsx b/front/src/modules/opportunities/components/BoardCard.tsx
index c7982172f..b6acc117c 100644
--- a/front/src/modules/opportunities/components/BoardCard.tsx
+++ b/front/src/modules/opportunities/components/BoardCard.tsx
@@ -1,5 +1,122 @@
import styled from '@emotion/styled';
-export const BoardCard = styled.p`
+import { Company, Person } from '../../../generated/graphql';
+import CompanyChip from '../../companies/components/CompanyChip';
+import PersonPlaceholder from '../../people/components/person-placeholder.png';
+import { PersonChip } from '../../people/components/PersonChip';
+import {
+ IconBuilding,
+ IconCalendar,
+ IconMail,
+ IconPhone,
+ IconSum,
+ IconUser,
+} from '../../ui/icons';
+import { getLogoUrlFromDomainName, humanReadableDate } from '../../utils/utils';
+
+const StyledBoardCard = styled.div`
color: ${(props) => props.theme.text80};
`;
+
+const StyledBoardCardHeader = styled.div`
+ align-items: center;
+ display: flex;
+ flex-direction: row;
+ font-weight: ${(props) => props.theme.fontWeightBold};
+ height: 24px;
+ padding: ${(props) => props.theme.spacing(2)};
+ img {
+ height: 16px;
+ margin-right: ${(props) => props.theme.spacing(2)};
+ object-fit: cover;
+ width: 16px;
+ }
+`;
+const StyledBoardCardBody = styled.div`
+ display: flex;
+ flex-direction: column;
+ gap: ${(props) => props.theme.spacing(2)};
+ padding: ${(props) => props.theme.spacing(2)};
+ span {
+ align-items: center;
+ display: flex;
+ flex-direction: row;
+ svg {
+ color: ${(props) => props.theme.text40};
+ margin-right: ${(props) => props.theme.spacing(2)};
+ }
+ }
+`;
+
+export const BoardCard = ({ item }: { item: Person | Company }) => {
+ if (item.__typename === 'Person') return ;
+ if (item.__typename === 'Company') return ;
+ // @todo return card skeleton
+ return null;
+};
+
+const PersonBoardCard = ({ person }: { person: Person }) => {
+ const fullname = `${person.firstname} ${person.lastname}`;
+ return (
+
+
+
+ {fullname}
+
+
+
+
+
+
+
+
+ {person.email}
+
+
+
+ {person.phone}
+
+
+
+ {humanReadableDate(new Date(person.createdAt as string))}
+
+
+
+ );
+};
+
+const CompanyBoardCard = ({ company }: { company: Company }) => {
+ return (
+
+
+
+ {company.name}
+
+
+
+
+
+
+
+ {company.employees}
+
+
+
+ {humanReadableDate(new Date(company.createdAt as string))}
+
+
+
+ );
+};
diff --git a/front/src/modules/opportunities/components/__stories__/BoardCard.stories.tsx b/front/src/modules/opportunities/components/__stories__/BoardCard.stories.tsx
new file mode 100644
index 000000000..cdf05e403
--- /dev/null
+++ b/front/src/modules/opportunities/components/__stories__/BoardCard.stories.tsx
@@ -0,0 +1,36 @@
+import { StrictMode } from 'react';
+import { Meta, StoryObj } from '@storybook/react';
+
+import { Company, Person } from '../../../../generated/graphql';
+import { mockedCompaniesData } from '../../../../testing/mock-data/companies';
+import { mockedPeopleData } from '../../../../testing/mock-data/people';
+import { BoardItem } from '../../../ui/components/board/BoardItem';
+import { BoardCard } from '../BoardCard';
+
+const meta: Meta = {
+ title: 'UI/Board/BoardCard',
+ component: BoardCard,
+};
+
+export default meta;
+type Story = StoryObj;
+
+export const CompanyBoardCard: Story = {
+ render: () => (
+
+
+
+
+
+ ),
+};
+
+export const PersonBoardCard: Story = {
+ render: () => (
+
+
+
+
+
+ ),
+};
diff --git a/front/src/modules/opportunities/components/__stories__/mock-data.ts b/front/src/modules/opportunities/components/__stories__/mock-data.ts
index a382080d3..618115aa0 100644
--- a/front/src/modules/opportunities/components/__stories__/mock-data.ts
+++ b/front/src/modules/opportunities/components/__stories__/mock-data.ts
@@ -1,16 +1,22 @@
+import { mockedCompaniesData } from '../../../../testing/mock-data/companies';
+import { mockedPeopleData } from '../../../../testing/mock-data/people';
import { Column, Items } from '../../../ui/components/board/Board';
export const items: Items = {
- 'item-1': { id: 'item-1', content: 'Item 1' },
- 'item-2': { id: 'item-2', content: 'Item 2' },
- 'item-3': { id: 'item-3', content: 'Item 3' },
- 'item-4': { id: 'item-4', content: 'Item 4' },
- 'item-5': { id: 'item-5', content: 'Item 5' },
- 'item-6': { id: 'item-6', content: 'Item 6' },
+ 'item-1': mockedCompaniesData[0],
+ 'item-2': mockedCompaniesData[1],
+ 'item-3': mockedCompaniesData[2],
+ 'item-4': mockedPeopleData[0],
+ 'item-5': mockedPeopleData[1],
+ 'item-6': mockedPeopleData[2],
};
+
for (let i = 7; i <= 20; i++) {
const key = `item-${i}`;
- items[key] = { id: key, content: `Item ${i}` };
+ items[key] = {
+ ...mockedCompaniesData[i % mockedCompaniesData.length],
+ id: key,
+ };
}
export const initialBoard = [
diff --git a/front/src/modules/people/interfaces/__tests__/person.interface.test.ts b/front/src/modules/people/interfaces/__tests__/person.interface.test.ts
index 3af788fdd..c0fdeae1a 100644
--- a/front/src/modules/people/interfaces/__tests__/person.interface.test.ts
+++ b/front/src/modules/people/interfaces/__tests__/person.interface.test.ts
@@ -39,7 +39,7 @@ describe('Person mappers', () => {
phone: graphQLPerson.phone,
_commentCount: 1,
company: {
- __typename: 'companies',
+ __typename: 'Company',
id: '7af20dea-0412-4c4c-8b13-d6f0e6e09e87',
accountOwner: undefined,
address: undefined,
diff --git a/front/src/modules/people/services/__tests__/update.test.ts b/front/src/modules/people/services/__tests__/update.test.ts
index a1c6ba88a..221d95403 100644
--- a/front/src/modules/people/services/__tests__/update.test.ts
+++ b/front/src/modules/people/services/__tests__/update.test.ts
@@ -31,7 +31,7 @@ it('updates a person', async () => {
id: '7dfbc3f7-6e5e-4128-957e-8d86808cdf6b',
name: 'ACME',
domainName: 'example.com',
- __typename: 'companies',
+ __typename: 'Company',
},
phone: '+1 (555) 123-4567',
pipes: [
diff --git a/front/src/modules/ui/components/board/Board.tsx b/front/src/modules/ui/components/board/Board.tsx
index d99e095e6..5222b5a59 100644
--- a/front/src/modules/ui/components/board/Board.tsx
+++ b/front/src/modules/ui/components/board/Board.tsx
@@ -8,10 +8,7 @@ export const StyledBoard = styled.div`
`;
export type BoardItemKey = `item-${number | string}`;
-export interface Item {
- id: string;
- content?: string;
-}
+export type Item = any & { id: string };
export interface Items {
[key: string]: Item;
}
diff --git a/front/src/modules/ui/components/board/BoardItem.tsx b/front/src/modules/ui/components/board/BoardItem.tsx
index eae767140..ec1bf5f3d 100644
--- a/front/src/modules/ui/components/board/BoardItem.tsx
+++ b/front/src/modules/ui/components/board/BoardItem.tsx
@@ -7,12 +7,12 @@ const StyledCard = styled.div`
border-radius: ${({ theme }) => theme.borderRadius};
box-shadow: ${({ theme }) => theme.boxShadow};
margin-bottom: ${({ theme }) => theme.spacing(2)};
- padding: ${({ theme }) => theme.spacing(2)};
+ max-width: 300px;
`;
type BoardCardProps = {
children: React.ReactNode;
- draggableProvided: DraggableProvided;
+ draggableProvided?: DraggableProvided;
};
export const BoardItem = ({ children, draggableProvided }: BoardCardProps) => {
diff --git a/front/src/modules/ui/components/board/__tests__/Board.test.ts b/front/src/modules/ui/components/board/__tests__/Board.test.ts
new file mode 100644
index 000000000..dc0171223
--- /dev/null
+++ b/front/src/modules/ui/components/board/__tests__/Board.test.ts
@@ -0,0 +1,55 @@
+import { DropResult } from '@hello-pangea/dnd';
+
+import { BoardItemKey, getOptimisticlyUpdatedBoard } from '../Board';
+
+describe('getOptimisticlyUpdatedBoard', () => {
+ it('should return a new board with the updated cell', () => {
+ const initialColumn1: BoardItemKey[] = ['item-1', 'item-2', 'item-3'];
+ const initialColumn2: BoardItemKey[] = ['item-4', 'item-5'];
+
+ const finalColumn1: BoardItemKey[] = ['item-2', 'item-3'];
+ const finalColumn2: BoardItemKey[] = ['item-4', 'item-1', 'item-5'];
+
+ const dropResult = {
+ source: {
+ droppableId: 'column-1',
+ index: 0,
+ },
+ destination: {
+ droppableId: 'column-2',
+ index: 1,
+ },
+ } as DropResult;
+
+ const initialBoard = [
+ {
+ id: 'column-1',
+ title: 'My Column',
+ itemKeys: initialColumn1,
+ },
+ {
+ id: 'column-2',
+ title: 'My Column',
+ itemKeys: initialColumn2,
+ },
+ ];
+
+ const updatedBoard = getOptimisticlyUpdatedBoard(initialBoard, dropResult);
+
+ const finalBoard = [
+ {
+ id: 'column-1',
+ title: 'My Column',
+ itemKeys: finalColumn1,
+ },
+ {
+ id: 'column-2',
+ title: 'My Column',
+ itemKeys: finalColumn2,
+ },
+ ];
+
+ expect(updatedBoard).toEqual(finalBoard);
+ expect(updatedBoard).not.toBe(initialBoard);
+ });
+});
diff --git a/front/src/modules/ui/components/table/EntityTable.tsx b/front/src/modules/ui/components/table/EntityTable.tsx
index c5811feee..5c6cf9296 100644
--- a/front/src/modules/ui/components/table/EntityTable.tsx
+++ b/front/src/modules/ui/components/table/EntityTable.tsx
@@ -24,7 +24,7 @@ import { currentRowSelectionState } from '../../tables/states/rowSelectionState'
import { TableHeader } from './table-header/TableHeader';
type OwnProps<
- TData extends { id: string; __typename: 'companies' | 'people' },
+ TData extends { id: string; __typename: 'Company' | 'people' },
SortField,
> = {
data: Array;
@@ -109,7 +109,7 @@ const StyledRow = styled.tr<{ selected: boolean }>`
`;
export function EntityTable<
- TData extends { id: string; __typename: 'companies' | 'people' },
+ TData extends { id: string; __typename: 'Company' | 'people' },
SortField,
>({
data,
diff --git a/front/src/pages/companies/Companies.tsx b/front/src/pages/companies/Companies.tsx
index 8f9068e3b..09c16c567 100644
--- a/front/src/pages/companies/Companies.tsx
+++ b/front/src/pages/companies/Companies.tsx
@@ -66,7 +66,7 @@ export function Companies() {
pipes: [],
createdAt: new Date(),
accountOwner: null,
- __typename: 'companies',
+ __typename: 'Company',
};
await insertCompany(newCompany);
diff --git a/front/src/pages/people/__tests__/people-filter.test.ts b/front/src/pages/people/__tests__/people-filter.test.ts
index 88d16c86d..a51e4a412 100644
--- a/front/src/pages/people/__tests__/people-filter.test.ts
+++ b/front/src/pages/people/__tests__/people-filter.test.ts
@@ -7,7 +7,7 @@ describe('PeopleFilter', () => {
id: 'test-id',
name: 'test-name',
domainName: 'test-domain-name',
- __typename: 'companies',
+ __typename: 'Company',
}),
).toMatchSnapshot();
});
diff --git a/front/src/testing/mock-data/companies.ts b/front/src/testing/mock-data/companies.ts
index e2ad27260..0a0503896 100644
--- a/front/src/testing/mock-data/companies.ts
+++ b/front/src/testing/mock-data/companies.ts
@@ -15,7 +15,7 @@ export const mockedCompaniesData: Array = [
id: '7dfbc3f7-6e5e-4128-957e-8d86808cdf6b',
__typename: 'users',
},
- __typename: 'companies',
+ __typename: 'Company',
},
{
id: 'b396e6b9-dc5c-4643-bcff-61b6cf7523ae',
@@ -26,7 +26,7 @@ export const mockedCompaniesData: Array = [
employees: 1,
_commentCount: 1,
accountOwner: null,
- __typename: 'companies',
+ __typename: 'Company',
},
{
id: 'a674fa6c-1455-4c57-afaf-dd5dc086361d',
@@ -37,7 +37,7 @@ export const mockedCompaniesData: Array = [
employees: 1,
_commentCount: 1,
accountOwner: null,
- __typename: 'companies',
+ __typename: 'Company',
},
{
id: 'b1cfd51b-a831-455f-ba07-4e30671e1dc3',
@@ -48,7 +48,7 @@ export const mockedCompaniesData: Array = [
employees: 10,
_commentCount: 0,
accountOwner: null,
- __typename: 'companies',
+ __typename: 'Company',
},
{
id: '5c21e19e-e049-4393-8c09-3e3f8fb09ecb',
@@ -59,7 +59,7 @@ export const mockedCompaniesData: Array = [
employees: 1,
_commentCount: 2,
accountOwner: null,
- __typename: 'companies',
+ __typename: 'Company',
},
{
id: '9d162de6-cfbf-4156-a790-e39854dcd4eb',
@@ -70,7 +70,7 @@ export const mockedCompaniesData: Array = [
employees: 1,
_commentCount: 13,
accountOwner: null,
- __typename: 'companies',
+ __typename: 'Company',
},
{
id: '9d162de6-cfbf-4156-a790-e39854dcd4ef',
@@ -81,6 +81,6 @@ export const mockedCompaniesData: Array = [
employees: 1,
_commentCount: 1,
accountOwner: null,
- __typename: 'companies',
+ __typename: 'Company',
},
];