Implement new UI
This commit is contained in:
@ -1,9 +0,0 @@
|
||||
function Contacts() {
|
||||
return (
|
||||
<div>
|
||||
<h1>This is the history page</h1>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default Contacts;
|
||||
@ -1,9 +0,0 @@
|
||||
function Insights() {
|
||||
return (
|
||||
<div>
|
||||
<h1>This is the insights page</h1>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default Insights;
|
||||
12
front/src/pages/companies/Companies.tsx
Normal file
12
front/src/pages/companies/Companies.tsx
Normal file
@ -0,0 +1,12 @@
|
||||
import { faBuilding } from '@fortawesome/free-regular-svg-icons';
|
||||
import WithTopBarContainer from '../../layout/containers/WithTopBarContainer';
|
||||
|
||||
function Companies() {
|
||||
return (
|
||||
<WithTopBarContainer title="Companies" icon={faBuilding}>
|
||||
<></>
|
||||
</WithTopBarContainer>
|
||||
);
|
||||
}
|
||||
|
||||
export default Companies;
|
||||
18
front/src/pages/companies/__stories__/Companies.stories.tsx
Normal file
18
front/src/pages/companies/__stories__/Companies.stories.tsx
Normal file
@ -0,0 +1,18 @@
|
||||
import { MemoryRouter } from 'react-router-dom';
|
||||
import Companies from '../Companies';
|
||||
import { ThemeProvider } from '@emotion/react';
|
||||
import { lightTheme } from '../../../layout/styles/themes';
|
||||
import AppLayout from '../../../layout/AppLayout';
|
||||
|
||||
export default {
|
||||
title: 'Companies',
|
||||
component: Companies,
|
||||
};
|
||||
|
||||
export const CompaniesDefault = () => (
|
||||
<ThemeProvider theme={lightTheme}>
|
||||
<MemoryRouter>
|
||||
<Companies />
|
||||
</MemoryRouter>
|
||||
</ThemeProvider>
|
||||
);
|
||||
10
front/src/pages/companies/__tests__/Companies.test.tsx
Normal file
10
front/src/pages/companies/__tests__/Companies.test.tsx
Normal file
@ -0,0 +1,10 @@
|
||||
import { render } from '@testing-library/react';
|
||||
|
||||
import { CompaniesDefault } from '../__stories__/Companies.stories';
|
||||
|
||||
it('Checks the Companies page render', () => {
|
||||
const { getByTestId } = render(<CompaniesDefault />);
|
||||
|
||||
const title = getByTestId('top-bar-title');
|
||||
expect(title).toHaveTextContent('Companies');
|
||||
});
|
||||
@ -1,18 +0,0 @@
|
||||
import FullWidthContainer from '../../layout/containers/FullWidthContainer';
|
||||
import DiscussionPanel from './discussion-panel/DiscussionPanel';
|
||||
import ListPanel from './list-panel/ListPanel';
|
||||
import PluginPanel from './plugin-panel/PluginPanel';
|
||||
|
||||
function Inbox() {
|
||||
return (
|
||||
<FullWidthContainer>
|
||||
<>
|
||||
<ListPanel />
|
||||
<DiscussionPanel />
|
||||
<PluginPanel />
|
||||
</>
|
||||
</FullWidthContainer>
|
||||
);
|
||||
}
|
||||
|
||||
export default Inbox;
|
||||
@ -1,13 +0,0 @@
|
||||
import { MemoryRouter } from 'react-router-dom';
|
||||
import Inbox from '../Inbox';
|
||||
|
||||
export default {
|
||||
title: 'Inbox',
|
||||
component: Inbox,
|
||||
};
|
||||
|
||||
export const InboxDefault = () => (
|
||||
<MemoryRouter>
|
||||
<Inbox />
|
||||
</MemoryRouter>
|
||||
);
|
||||
@ -1,10 +0,0 @@
|
||||
import { render } from '@testing-library/react';
|
||||
|
||||
import { InboxDefault } from '../__stories__/Inbox.stories';
|
||||
|
||||
it('Checks the Inbox page render', () => {
|
||||
const { getAllByRole } = render(<InboxDefault />);
|
||||
|
||||
const button = getAllByRole('button');
|
||||
expect(button[0]).toHaveTextContent('Sylvie Vartan');
|
||||
});
|
||||
@ -1,100 +0,0 @@
|
||||
import styled from '@emotion/styled';
|
||||
import Composer from './composer/Composer';
|
||||
import Booking, { BookingEvent } from './events/Booking';
|
||||
import Message, { MessageEvent } from './events/Message';
|
||||
import Note, { NoteEvent } from './events/Note';
|
||||
|
||||
export type Event = BookingEvent | MessageEvent | NoteEvent;
|
||||
|
||||
const StyledPanel = styled.div`
|
||||
display: flex;
|
||||
flex-grow: 1;
|
||||
flex-direction: column;
|
||||
`;
|
||||
|
||||
const EventsContainer = styled.div`
|
||||
display: flex;
|
||||
flex-grow: 1;
|
||||
flex-direction: column;
|
||||
padding: 32px;
|
||||
`;
|
||||
|
||||
const StyledToday = styled.div`
|
||||
font-size: 12px;
|
||||
color: #2e3138;
|
||||
border-bottom: 1px solid #eaecee;
|
||||
margin-top: 32px;
|
||||
padding-bottom: 8px;
|
||||
margin-bottom: 8px;
|
||||
`;
|
||||
|
||||
const ComposerContainer = styled.div`
|
||||
display: flex;
|
||||
padding: 32px;
|
||||
flex-direction: column;
|
||||
flex-grow: 1;
|
||||
`;
|
||||
|
||||
function DiscussionPanel() {
|
||||
return (
|
||||
<StyledPanel>
|
||||
<EventsContainer>
|
||||
<Booking
|
||||
booking={{
|
||||
id: 1,
|
||||
time: 'Wed, Sep 10, 2022',
|
||||
user: 'Georges',
|
||||
nights: 4,
|
||||
guests: 5,
|
||||
price: '756.90$',
|
||||
listing: 'Rochefort Montagne',
|
||||
dateRange: 'Mon, Sep 30 - Fri, Oct 2',
|
||||
}}
|
||||
/>
|
||||
<StyledToday>Today</StyledToday>
|
||||
<Message
|
||||
message={{
|
||||
id: 1,
|
||||
time: '2 hours ago',
|
||||
user: 'Georges Alain',
|
||||
channel: 'sms',
|
||||
message:
|
||||
'I’m looking for my order but couldn’t find it. Could you help me find it. I don’t know where to look for.',
|
||||
}}
|
||||
/>
|
||||
<Message
|
||||
message={{
|
||||
id: 2,
|
||||
time: 'just now',
|
||||
user: 'Support',
|
||||
channel: 'sms',
|
||||
message: 'Hello I’m here bla bla bla',
|
||||
agent: 'Leslie A',
|
||||
}}
|
||||
/>
|
||||
<Note
|
||||
note={{
|
||||
id: 1,
|
||||
time: 'just now',
|
||||
agent: 'LeslieA',
|
||||
message: 'Hello I’m here bla bla bla',
|
||||
}}
|
||||
/>
|
||||
<Message
|
||||
message={{
|
||||
id: 3,
|
||||
time: 'just now',
|
||||
user: 'Georges Alain',
|
||||
channel: 'sms',
|
||||
message: 'Thank you !',
|
||||
}}
|
||||
/>
|
||||
</EventsContainer>
|
||||
<ComposerContainer>
|
||||
<Composer />
|
||||
</ComposerContainer>
|
||||
</StyledPanel>
|
||||
);
|
||||
}
|
||||
|
||||
export default DiscussionPanel;
|
||||
@ -1,8 +0,0 @@
|
||||
import DiscussionPanel from '../DiscussionPanel';
|
||||
|
||||
export default {
|
||||
title: 'DiscussionPanel',
|
||||
component: DiscussionPanel,
|
||||
};
|
||||
|
||||
export const DiscussionPanelDefault = () => <DiscussionPanel />;
|
||||
@ -1,10 +0,0 @@
|
||||
import { render } from '@testing-library/react';
|
||||
|
||||
import { DiscussionPanelDefault } from '../__stories__/DiscussionPanel.stories';
|
||||
|
||||
it('Checks the discussion panel render', () => {
|
||||
const { getAllByText } = render(<DiscussionPanelDefault />);
|
||||
|
||||
const text = getAllByText('Rochefort Montagne');
|
||||
expect(text).toBeDefined();
|
||||
});
|
||||
@ -1,57 +0,0 @@
|
||||
import styled from '@emotion/styled';
|
||||
import ComposerSwitch from './ComposerSwitch';
|
||||
|
||||
const StyledContainer = styled.div`
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
border: 2px solid #000000;
|
||||
border-radius: 12px;
|
||||
`;
|
||||
|
||||
const StyledInputContainer = styled.div`
|
||||
display: flex;
|
||||
padding: 8px;
|
||||
justify-content: center;
|
||||
& > textarea {
|
||||
width: 95%;
|
||||
border: none;
|
||||
outline: none;
|
||||
font-family: 'Source Sans Pro';
|
||||
|
||||
&::placeholder {
|
||||
font-family: 'Source Sans Pro';
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
const ActionContainer = styled.div`
|
||||
display: flex;
|
||||
padding: 16px;
|
||||
justify-content: flex-end;
|
||||
`;
|
||||
|
||||
const PrimaryButton = styled.button`
|
||||
background: black;
|
||||
font-weight: bold;
|
||||
color: white;
|
||||
padding: 16px 24px;
|
||||
border: 0;
|
||||
border-radius: 12px;
|
||||
cursor: pointer;
|
||||
`;
|
||||
|
||||
function Composer() {
|
||||
return (
|
||||
<StyledContainer>
|
||||
<ComposerSwitch />
|
||||
<StyledInputContainer>
|
||||
<textarea rows={5} placeholder="Type to chat..."></textarea>
|
||||
</StyledInputContainer>
|
||||
<ActionContainer>
|
||||
<PrimaryButton>Reply by SMS</PrimaryButton>
|
||||
</ActionContainer>
|
||||
</StyledContainer>
|
||||
);
|
||||
}
|
||||
|
||||
export default Composer;
|
||||
@ -1,49 +0,0 @@
|
||||
import styled from '@emotion/styled';
|
||||
|
||||
const StyledContainer = styled.div`
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
border-bottom: 2px solid #eaecee;
|
||||
padding: 0px 12px;
|
||||
`;
|
||||
|
||||
const SwitchTab = styled.button`
|
||||
display: flex;
|
||||
border-bottom: 2px solid #eaecee;
|
||||
margin-bottom: -2px;
|
||||
padding: 12px;
|
||||
cursor: pointer;
|
||||
color: #2e3138;
|
||||
background: inherit;
|
||||
border: 0;
|
||||
|
||||
&:hover {
|
||||
border-bottom: 2px solid #2e3138;
|
||||
}
|
||||
`;
|
||||
|
||||
const SwitchTabActive = styled.button`
|
||||
display: flex;
|
||||
border: 0;
|
||||
border-bottom: 2px solid black;
|
||||
margin-bottom: -2px;
|
||||
padding: 12px;
|
||||
cursor: pointer;
|
||||
color: black;
|
||||
font-weight: bold;
|
||||
background: inherit;
|
||||
`;
|
||||
|
||||
function ComposerSwitch() {
|
||||
return (
|
||||
<StyledContainer>
|
||||
<SwitchTabActive>Reply</SwitchTabActive>
|
||||
<SwitchTab>Call</SwitchTab>
|
||||
<SwitchTab>Note</SwitchTab>
|
||||
<SwitchTab>Transfer</SwitchTab>
|
||||
<SwitchTab>Help</SwitchTab>
|
||||
</StyledContainer>
|
||||
);
|
||||
}
|
||||
|
||||
export default ComposerSwitch;
|
||||
@ -1,8 +0,0 @@
|
||||
import Composer from '../Composer';
|
||||
|
||||
export default {
|
||||
title: 'Composer',
|
||||
component: Composer,
|
||||
};
|
||||
|
||||
export const ComposerDefault = () => <Composer />;
|
||||
@ -1,8 +0,0 @@
|
||||
import ComposerSwitch from '../ComposerSwitch';
|
||||
|
||||
export default {
|
||||
title: 'Composer',
|
||||
component: ComposerSwitch,
|
||||
};
|
||||
|
||||
export const ComposerSwithDefault = () => <ComposerSwitch />;
|
||||
@ -1,10 +0,0 @@
|
||||
import { render } from '@testing-library/react';
|
||||
|
||||
import { ComposerDefault } from '../__stories__/Composer.stories';
|
||||
|
||||
it('Checks the composer render', () => {
|
||||
const { getAllByRole } = render(<ComposerDefault />);
|
||||
|
||||
const button = getAllByRole('button');
|
||||
expect(button[0]).toHaveTextContent('Reply');
|
||||
});
|
||||
@ -1,10 +0,0 @@
|
||||
import { render } from '@testing-library/react';
|
||||
|
||||
import { ComposerSwithDefault } from '../__stories__/ComposerSwitch.stories';
|
||||
|
||||
it('Checks the composer switch render', () => {
|
||||
const { getAllByRole } = render(<ComposerSwithDefault />);
|
||||
|
||||
const button = getAllByRole('button');
|
||||
expect(button[0]).toHaveTextContent('Reply');
|
||||
});
|
||||
@ -1,80 +0,0 @@
|
||||
import styled from '@emotion/styled';
|
||||
|
||||
export type BookingEvent = {
|
||||
id: number;
|
||||
user: string;
|
||||
time: string;
|
||||
listing: string;
|
||||
nights: number;
|
||||
guests: number;
|
||||
price: string;
|
||||
dateRange: string;
|
||||
};
|
||||
|
||||
type OwnProps = {
|
||||
booking: BookingEvent;
|
||||
};
|
||||
|
||||
const StyledBooking = styled.div`
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
`;
|
||||
|
||||
const StyledLabel = styled.div`
|
||||
font-size: 12px;
|
||||
color: #2e3138;
|
||||
margin-bottom: 8px;
|
||||
`;
|
||||
|
||||
const StyledContainer = styled.div`
|
||||
display: flex;
|
||||
padding: 16px;
|
||||
flex-direction: row;
|
||||
border: 1px solid #000000;
|
||||
border-radius: 12px;
|
||||
`;
|
||||
|
||||
const StyledPicture = styled.div`
|
||||
background: #2e3138;
|
||||
width: 50px;
|
||||
height: 42px;
|
||||
margin-right: 16px;
|
||||
`;
|
||||
|
||||
const StyledContent = styled.div`
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
`;
|
||||
|
||||
const StyledListing = styled.div`
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
`;
|
||||
|
||||
const StyledDetails = styled.div`
|
||||
font-size: 12px;
|
||||
color: #2e3138;
|
||||
`;
|
||||
|
||||
function Booking({ booking }: OwnProps) {
|
||||
return (
|
||||
<StyledBooking>
|
||||
<StyledLabel>
|
||||
{booking.time} · {booking.user} booked a trip
|
||||
</StyledLabel>
|
||||
<StyledContainer>
|
||||
<StyledPicture />
|
||||
<StyledContent>
|
||||
<StyledListing>{booking.listing}</StyledListing>
|
||||
<StyledDetails>
|
||||
{booking.dateRange} · {booking.nights} nights · {booking.guests}{' '}
|
||||
guests · {booking.price}
|
||||
</StyledDetails>
|
||||
</StyledContent>
|
||||
</StyledContainer>
|
||||
</StyledBooking>
|
||||
);
|
||||
}
|
||||
|
||||
export default Booking;
|
||||
@ -1,90 +0,0 @@
|
||||
import styled from '@emotion/styled';
|
||||
|
||||
export type MessageEvent = {
|
||||
id: number;
|
||||
user: string;
|
||||
time: string;
|
||||
channel: string;
|
||||
message: string;
|
||||
agent?: string;
|
||||
};
|
||||
|
||||
type OwnProps = {
|
||||
message: MessageEvent;
|
||||
};
|
||||
|
||||
const StyledMessage = styled.div`
|
||||
display: flex;
|
||||
margin-top: 12px;
|
||||
margin-bottom: 20px;
|
||||
`;
|
||||
|
||||
const StyledAvatar = styled.div`
|
||||
display: flex;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
border-radius: 40px;
|
||||
background: black;
|
||||
font-size: 20px;
|
||||
color: white;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-weight: bold;
|
||||
margin-right: 16px;
|
||||
flex-shrink: 0;
|
||||
`;
|
||||
|
||||
const StyledContent = styled.div``;
|
||||
|
||||
const StyledTitle = styled.div`
|
||||
display: flex;
|
||||
align-items: center;
|
||||
`;
|
||||
|
||||
const StyledUser = styled.div`
|
||||
font-size: 16px;
|
||||
color: black;
|
||||
font-weight: bold;
|
||||
`;
|
||||
|
||||
const StyledTime = styled.div`
|
||||
margin-left: 8px;
|
||||
font-size: 12px;
|
||||
color: #2e3138;
|
||||
`;
|
||||
|
||||
const StyledAgent = styled.div`
|
||||
text-decoration: underline;
|
||||
margin-left: 4px;
|
||||
font-size: 12px;
|
||||
color: #2e3138;
|
||||
`;
|
||||
|
||||
const StyledDetails = styled.div`
|
||||
margin-top: 8px;
|
||||
`;
|
||||
|
||||
function Message({ message }: OwnProps) {
|
||||
return (
|
||||
<StyledMessage>
|
||||
<StyledAvatar>
|
||||
{message.user
|
||||
.split(' ')
|
||||
.map((n) => n[0])
|
||||
.join('')}
|
||||
</StyledAvatar>
|
||||
<StyledContent>
|
||||
<StyledTitle>
|
||||
<StyledUser>{message.user}</StyledUser>
|
||||
<StyledTime>
|
||||
{message.time} ({message.channel})
|
||||
</StyledTime>
|
||||
{message.agent && <StyledAgent>by {message.agent}</StyledAgent>}
|
||||
</StyledTitle>
|
||||
<StyledDetails>{message.message}</StyledDetails>
|
||||
</StyledContent>
|
||||
</StyledMessage>
|
||||
);
|
||||
}
|
||||
|
||||
export default Message;
|
||||
@ -1,52 +0,0 @@
|
||||
import styled from '@emotion/styled';
|
||||
|
||||
export type NoteEvent = {
|
||||
id: number;
|
||||
time: string;
|
||||
message: string;
|
||||
agent: string;
|
||||
};
|
||||
|
||||
type OwnProps = {
|
||||
note: NoteEvent;
|
||||
};
|
||||
|
||||
const StyledNote = styled.div`
|
||||
display: flex;
|
||||
background: #f8f9fa;
|
||||
border-left: 4px solid black;
|
||||
padding: 8px 20px;
|
||||
flex-direction: column;
|
||||
margin-top: 12px;
|
||||
margin-bottom: 20px;
|
||||
`;
|
||||
|
||||
const StyledLabel = styled.div`
|
||||
font-size: 12px;
|
||||
color: #2e3138;
|
||||
margin-bottom: 8px;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
`;
|
||||
|
||||
const StyledAgent = styled.div`
|
||||
text-decoration: underline;
|
||||
margin-left: 4px;
|
||||
font-size: 12px;
|
||||
color: #2e3138;
|
||||
`;
|
||||
|
||||
const StyledMessage = styled.div``;
|
||||
|
||||
function Note({ note }: OwnProps) {
|
||||
return (
|
||||
<StyledNote>
|
||||
<StyledLabel>
|
||||
Internal Note {note.time} <StyledAgent>by {note.agent}</StyledAgent>
|
||||
</StyledLabel>
|
||||
<StyledMessage>{note.message}</StyledMessage>
|
||||
</StyledNote>
|
||||
);
|
||||
}
|
||||
|
||||
export default Note;
|
||||
@ -1,21 +0,0 @@
|
||||
import Booking from '../Booking';
|
||||
|
||||
export default {
|
||||
title: 'DiscussionPanel',
|
||||
component: Booking,
|
||||
};
|
||||
|
||||
export const BookingDefault = () => (
|
||||
<Booking
|
||||
booking={{
|
||||
id: 1,
|
||||
time: 'Wed, Sep 10, 2022',
|
||||
user: 'Georges',
|
||||
nights: 4,
|
||||
guests: 5,
|
||||
price: '756.90$',
|
||||
listing: 'Rochefort Montagne',
|
||||
dateRange: 'Mon, Sep 30 - Fri, Oct 2',
|
||||
}}
|
||||
/>
|
||||
);
|
||||
@ -1,19 +0,0 @@
|
||||
import Message from '../Message';
|
||||
|
||||
export default {
|
||||
title: 'DiscussionPanel',
|
||||
component: Message,
|
||||
};
|
||||
|
||||
export const MessageDefault = () => (
|
||||
<Message
|
||||
message={{
|
||||
id: 1,
|
||||
time: '2 hours ago',
|
||||
user: 'Georges Alain',
|
||||
channel: 'sms',
|
||||
message:
|
||||
'I’m looking for my order but couldn’t find it. Could you help me find it. I don’t know where to look for.',
|
||||
}}
|
||||
/>
|
||||
);
|
||||
@ -1,17 +0,0 @@
|
||||
import Note from '../Note';
|
||||
|
||||
export default {
|
||||
title: 'DiscussionPanel',
|
||||
component: Note,
|
||||
};
|
||||
|
||||
export const NoteDefault = () => (
|
||||
<Note
|
||||
note={{
|
||||
id: 1,
|
||||
time: 'just now',
|
||||
agent: 'LeslieA',
|
||||
message: 'Hello I’m here bla bla bla',
|
||||
}}
|
||||
/>
|
||||
);
|
||||
@ -1,10 +0,0 @@
|
||||
import { render } from '@testing-library/react';
|
||||
|
||||
import { BookingDefault } from '../__stories__/Booking.stories';
|
||||
|
||||
it('Checks the booking event render', () => {
|
||||
const { getAllByText } = render(<BookingDefault />);
|
||||
|
||||
const text = getAllByText('Rochefort Montagne');
|
||||
expect(text).toBeDefined();
|
||||
});
|
||||
@ -1,10 +0,0 @@
|
||||
import { render } from '@testing-library/react';
|
||||
|
||||
import { MessageDefault } from '../__stories__/Message.stories';
|
||||
|
||||
it('Checks the booking event render', () => {
|
||||
const { getAllByText } = render(<MessageDefault />);
|
||||
|
||||
const text = getAllByText('Georges Alain');
|
||||
expect(text).toBeDefined();
|
||||
});
|
||||
@ -1,10 +0,0 @@
|
||||
import { render } from '@testing-library/react';
|
||||
|
||||
import { NoteDefault } from '../__stories__/Note.stories';
|
||||
|
||||
it('Checks the booking event render', () => {
|
||||
const { getAllByText } = render(<NoteDefault />);
|
||||
|
||||
const text = getAllByText('Hello I’m here bla bla bla');
|
||||
expect(text).toBeDefined();
|
||||
});
|
||||
@ -1,50 +0,0 @@
|
||||
import styled from '@emotion/styled';
|
||||
import ListPanelHeader from './ListPanelHeader';
|
||||
import ListPanelItem from './ListPanelItem';
|
||||
|
||||
const StyledList = styled.div`
|
||||
display: flex;
|
||||
width: 325px;
|
||||
flex-direction: column;
|
||||
border-right: 2px solid #eaecee;
|
||||
`;
|
||||
|
||||
export type Task = {
|
||||
id: number;
|
||||
targetUser: string;
|
||||
label: string;
|
||||
time: string;
|
||||
lastMessage: string;
|
||||
};
|
||||
|
||||
function ListPanel() {
|
||||
const tasks: Task[] = [
|
||||
{
|
||||
id: 1,
|
||||
targetUser: 'Sylvie Vartan',
|
||||
label: 'Guest at #xxx property',
|
||||
time: '3h',
|
||||
lastMessage:
|
||||
'I’m looking for my order but couldn’t find it. Could you help me find it. I don’t know where ...',
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
targetUser: 'Johnny Halliday',
|
||||
label: 'Guest at #xxx property',
|
||||
time: '4h',
|
||||
lastMessage: 'Hello, this is Johnny',
|
||||
},
|
||||
];
|
||||
return (
|
||||
<StyledList>
|
||||
<>
|
||||
<ListPanelHeader />
|
||||
{tasks.map((item) => (
|
||||
<ListPanelItem key={item.id} task={item} />
|
||||
))}
|
||||
</>
|
||||
</StyledList>
|
||||
);
|
||||
}
|
||||
|
||||
export default ListPanel;
|
||||
@ -1,17 +0,0 @@
|
||||
import styled from '@emotion/styled';
|
||||
|
||||
const StyledHeader = styled.div`
|
||||
display: flex;
|
||||
font-weight: bold;
|
||||
align-items: center;
|
||||
padding: 16px 24px;
|
||||
font-size: 18px;
|
||||
letter-spacing: 1px;
|
||||
border-bottom: 1px solid #eaecee;
|
||||
`;
|
||||
|
||||
function ListPanelHeader() {
|
||||
return <StyledHeader>6 tasks waiting</StyledHeader>;
|
||||
}
|
||||
|
||||
export default ListPanelHeader;
|
||||
@ -1,98 +0,0 @@
|
||||
import styled from '@emotion/styled';
|
||||
import { Task } from './ListPanel';
|
||||
|
||||
type OwnProps = {
|
||||
task: Task;
|
||||
};
|
||||
|
||||
const StyledListItem = styled.button`
|
||||
display: flex;
|
||||
padding: 16px 24px;
|
||||
flex-direction: column;
|
||||
color: #2e3138;
|
||||
border: 0;
|
||||
border-bottom: 1px solid #eaecee;
|
||||
cursor: pointer;
|
||||
font-family: inherit;
|
||||
text-align: inherit;
|
||||
align-items: inherit;
|
||||
background: #f1f3f5;
|
||||
`;
|
||||
|
||||
const StyledHeader = styled.div`
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
`;
|
||||
|
||||
const StyledAvatarAndTitle = styled.div`
|
||||
display: flex;
|
||||
`;
|
||||
|
||||
const StyledAvatar = styled.div`
|
||||
display: flex;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
border-radius: 40px;
|
||||
background: #52555b;
|
||||
font-size: 20px;
|
||||
color: white;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-weight: bold;
|
||||
`;
|
||||
|
||||
const StyledTitle = styled.div`
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
margin-left: 8px;
|
||||
`;
|
||||
|
||||
const StyledName = styled.div`
|
||||
font-weight: bold;
|
||||
font-size: 18px;
|
||||
color: black;
|
||||
`;
|
||||
|
||||
const StyledLabel = styled.div`
|
||||
display: flex;
|
||||
font-size: 14px;
|
||||
`;
|
||||
|
||||
const StyledTime = styled.div`
|
||||
display: flex;
|
||||
justify-self: flex-end;
|
||||
color: #7d8187;
|
||||
font-size: 14px;
|
||||
`;
|
||||
|
||||
const StyledContent = styled.div`
|
||||
display: flex;
|
||||
color: #52555b;
|
||||
font-size: 14px;
|
||||
margin-top: 8px;
|
||||
`;
|
||||
|
||||
function ListPanelItem({ task }: OwnProps) {
|
||||
return (
|
||||
<StyledListItem>
|
||||
<StyledHeader>
|
||||
<StyledAvatarAndTitle>
|
||||
<StyledAvatar>
|
||||
{task.targetUser
|
||||
.split(' ')
|
||||
.map((n) => n[0])
|
||||
.join('')}
|
||||
</StyledAvatar>
|
||||
<StyledTitle>
|
||||
<StyledName>{task.targetUser}</StyledName>
|
||||
<StyledLabel>{task.label}</StyledLabel>
|
||||
</StyledTitle>
|
||||
</StyledAvatarAndTitle>
|
||||
<StyledTime>{task.time}</StyledTime>
|
||||
</StyledHeader>
|
||||
<StyledContent>{task.lastMessage} </StyledContent>
|
||||
</StyledListItem>
|
||||
);
|
||||
}
|
||||
|
||||
export default ListPanelItem;
|
||||
@ -1,8 +0,0 @@
|
||||
import ListPanel from '../ListPanel';
|
||||
|
||||
export default {
|
||||
title: 'ListPanel',
|
||||
component: ListPanel,
|
||||
};
|
||||
|
||||
export const ListPanelDefault = () => <ListPanel />;
|
||||
@ -1,9 +0,0 @@
|
||||
import { MemoryRouter } from 'react-router-dom';
|
||||
import ListPanelHeader from '../ListPanelHeader';
|
||||
|
||||
export default {
|
||||
title: 'ListPanel',
|
||||
component: ListPanelHeader,
|
||||
};
|
||||
|
||||
export const ListPanelHeaderDefault = () => <ListPanelHeader />;
|
||||
@ -1,19 +0,0 @@
|
||||
import ListPanelItem from '../ListPanelItem';
|
||||
|
||||
export default {
|
||||
title: 'ListPanel',
|
||||
component: ListPanelItem,
|
||||
};
|
||||
|
||||
export const ListPanelItemDefault = () => (
|
||||
<ListPanelItem
|
||||
task={{
|
||||
id: 1,
|
||||
targetUser: 'Sylvie Vartan',
|
||||
label: 'Guest at #xxx property',
|
||||
time: '3h',
|
||||
lastMessage:
|
||||
'I’m looking for my order but couldn’t find it. Could you help me find it. I don’t know where ...',
|
||||
}}
|
||||
/>
|
||||
);
|
||||
@ -1,10 +0,0 @@
|
||||
import { render } from '@testing-library/react';
|
||||
|
||||
import { ListPanelDefault } from '../__stories__/ListPanel.stories';
|
||||
|
||||
it('Checks the task list render', () => {
|
||||
const { getAllByRole } = render(<ListPanelDefault />);
|
||||
|
||||
const button = getAllByRole('button');
|
||||
expect(button[0]).toHaveTextContent('Sylvie Vartan');
|
||||
});
|
||||
@ -1,10 +0,0 @@
|
||||
import { render } from '@testing-library/react';
|
||||
|
||||
import { ListPanelHeaderDefault } from '../__stories__/ListPanelHeader.stories';
|
||||
|
||||
it('Checks the ListPanelHeader render', () => {
|
||||
const { getAllByText } = render(<ListPanelHeaderDefault />);
|
||||
|
||||
const text = getAllByText('6 tasks waiting');
|
||||
expect(text).toBeDefined();
|
||||
});
|
||||
@ -1,10 +0,0 @@
|
||||
import { render } from '@testing-library/react';
|
||||
|
||||
import { ListPanelItemDefault } from '../__stories__/ListPanelItem.stories';
|
||||
|
||||
it('Checks the ListPanelItem render', () => {
|
||||
const { getAllByText } = render(<ListPanelItemDefault />);
|
||||
|
||||
const text = getAllByText('Sylvie Vartan');
|
||||
expect(text).toBeDefined();
|
||||
});
|
||||
@ -1,27 +0,0 @@
|
||||
import styled from '@emotion/styled';
|
||||
import PluginPanelNav from './PluginPanelNav';
|
||||
import PluginHistory from './plugin-history/PanelHistory';
|
||||
|
||||
const StyledPanel = styled.div`
|
||||
display: flex;
|
||||
width: 350px;
|
||||
border-left: 1px solid #eaecee;
|
||||
`;
|
||||
|
||||
const StyledContainer = styled.div`
|
||||
display: flex;
|
||||
flex-grow: 1;
|
||||
`;
|
||||
|
||||
function PluginPanel() {
|
||||
return (
|
||||
<StyledPanel>
|
||||
<StyledContainer>
|
||||
<PluginHistory />
|
||||
</StyledContainer>
|
||||
<PluginPanelNav />
|
||||
</StyledPanel>
|
||||
);
|
||||
}
|
||||
|
||||
export default PluginPanel;
|
||||
@ -1,46 +0,0 @@
|
||||
import styled from '@emotion/styled';
|
||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
||||
import { faClone } from '@fortawesome/free-regular-svg-icons';
|
||||
|
||||
const StyledNav = styled.div`
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 60px;
|
||||
border-left: 1px solid #eaecee;
|
||||
background: #f1f3f5;
|
||||
`;
|
||||
|
||||
const StyledNavItem = styled.div`
|
||||
display: flex;
|
||||
width: 60px;
|
||||
border-bottom: 1px solid #eaecee;
|
||||
padding: 22px;
|
||||
cursor: pointer;
|
||||
`;
|
||||
|
||||
function PluginPanelNav() {
|
||||
return (
|
||||
<StyledNav>
|
||||
<StyledNavItem>
|
||||
<FontAwesomeIcon icon={faClone} size="lg" />
|
||||
</StyledNavItem>
|
||||
<StyledNavItem>
|
||||
<FontAwesomeIcon icon={faClone} size="lg" />
|
||||
</StyledNavItem>
|
||||
<StyledNavItem>
|
||||
<FontAwesomeIcon icon={faClone} size="lg" />
|
||||
</StyledNavItem>
|
||||
<StyledNavItem>
|
||||
<FontAwesomeIcon icon={faClone} size="lg" />
|
||||
</StyledNavItem>
|
||||
<StyledNavItem>
|
||||
<FontAwesomeIcon icon={faClone} size="lg" />
|
||||
</StyledNavItem>
|
||||
<StyledNavItem>
|
||||
<FontAwesomeIcon icon={faClone} size="lg" />
|
||||
</StyledNavItem>
|
||||
</StyledNav>
|
||||
);
|
||||
}
|
||||
|
||||
export default PluginPanelNav;
|
||||
@ -1,5 +0,0 @@
|
||||
function PluginHistory() {
|
||||
return <div></div>;
|
||||
}
|
||||
|
||||
export default PluginHistory;
|
||||
@ -1,7 +0,0 @@
|
||||
import styled from '@emotion/styled';
|
||||
|
||||
function UserActivity() {
|
||||
return;
|
||||
}
|
||||
|
||||
export default UserActivity;
|
||||
@ -1,7 +0,0 @@
|
||||
import styled from '@emotion/styled';
|
||||
|
||||
function UserInformation() {
|
||||
return;
|
||||
}
|
||||
|
||||
export default UserInformation;
|
||||
12
front/src/pages/people/People.tsx
Normal file
12
front/src/pages/people/People.tsx
Normal file
@ -0,0 +1,12 @@
|
||||
import { faUser } from '@fortawesome/free-regular-svg-icons';
|
||||
import WithTopBarContainer from '../../layout/containers/WithTopBarContainer';
|
||||
|
||||
function People() {
|
||||
return (
|
||||
<WithTopBarContainer title="People" icon={faUser}>
|
||||
<></>
|
||||
</WithTopBarContainer>
|
||||
);
|
||||
}
|
||||
|
||||
export default People;
|
||||
17
front/src/pages/people/__stories__/People.stories.tsx
Normal file
17
front/src/pages/people/__stories__/People.stories.tsx
Normal file
@ -0,0 +1,17 @@
|
||||
import { MemoryRouter } from 'react-router-dom';
|
||||
import People from '../People';
|
||||
import { ThemeProvider } from '@emotion/react';
|
||||
import { lightTheme } from '../../../layout/styles/themes';
|
||||
|
||||
export default {
|
||||
title: 'People',
|
||||
component: People,
|
||||
};
|
||||
|
||||
export const PeopleDefault = () => (
|
||||
<ThemeProvider theme={lightTheme}>
|
||||
<MemoryRouter>
|
||||
<People />
|
||||
</MemoryRouter>
|
||||
</ThemeProvider>
|
||||
);
|
||||
10
front/src/pages/people/__tests__/People.test.tsx
Normal file
10
front/src/pages/people/__tests__/People.test.tsx
Normal file
@ -0,0 +1,10 @@
|
||||
import { render } from '@testing-library/react';
|
||||
|
||||
import { PeopleDefault } from '../__stories__/People.stories';
|
||||
|
||||
it('Checks the People page render', () => {
|
||||
const { getByTestId } = render(<PeopleDefault />);
|
||||
|
||||
const title = getByTestId('top-bar-title');
|
||||
expect(title).toHaveTextContent('People');
|
||||
});
|
||||
Reference in New Issue
Block a user