Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat/offers revisited #1157

Merged
merged 3 commits into from
Nov 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import React from 'react';
import OffersList from './offers-list';

export default {
title: 'Design Library/Molecules/OffersList',
component: OffersList,
};

const Template = (args) => <OffersList {...args} />;

export const Default = Template.bind({});
Default.args = {
offers: [
{
User: {
username: 'username',
picture_url: 'https://via.placeholder.com/150',
name: 'name',
},
status: 'status',
value: 100,
suggestedDate: new Date(),
},
],
onMessage: (id) => console.log('onMessage', id),
assigned: false,
onAccept: (id) => console.log('onAccept', id),
onReject: (id) => console.log('onReject', id),
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
import React from 'react';
import {
Button,
Chip,
Typography,
List,
ListItem,
ListItemText,
ListItemAvatar,
Avatar,
Divider
} from '@material-ui/core';
import MessageIcon from '@mui/icons-material/Message';
import MomentComponent from 'moment';
import { FormattedMessage } from 'react-intl';

interface OfferListProps {
offers: any;
onMessage?: any;
assigned?: boolean;
onAccept?: any;
onReject?: any;
viewMode?: boolean;
}


export default function OffersList({
offers,
onMessage,
assigned,
onAccept,
onReject,
viewMode
}:OfferListProps) {
const onSendMessage = (id) => {
onMessage(id);
}

return (
<List style={{ width: '100%' }}>
{offers?.map((offer) => (
<>
<ListItem alignItems="flex-start">
<ListItemAvatar>
<Avatar alt={ offer?.User?.username } src={ offer?.User?.picture_url} />
</ListItemAvatar>
<ListItemText
primary={
<>
{offer?.User?.username || offer?.User?.name}
<Chip
label={offer?.status || 'pending'}
color='secondary'
variant="default"
size='small'
style={{marginLeft: 10, display: 'inline-block'}}
/>
</>
}
secondary={
<div style={{display: 'flex', justifyContent: 'space-between'}}>
<div>
<Typography
style={{ display: 'inline-block' }}
variant="subtitle1"
color="primary"
>
{ offer?.User?.name }
</Typography>
<Typography variant="subtitle2" color="secondary" gutterBottom>
$ {offer?.value}
</Typography>
{ offer?.suggestedDate &&
<Typography variant="caption" color="secondary" gutterBottom>
Finish {MomentComponent(offer?.suggestedDate).fromNow()}
</Typography>
}
{ offer?.comment &&
<Typography variant="body1" color="secondary" component='div' gutterBottom>
Comment:<br />
{offer?.comment}
</Typography>
}
{ offer?.learn &&
<Typography variant="body1" color="secondary" gutterBottom>
<FormattedMessage id='task.learn' defaultMessage={'For learning purposes'} />
</Typography>
}
{ offer?.createdAt &&
<Typography variant="caption" color="secondary" gutterBottom>
{ MomentComponent(offer?.createdAt).fromNow() }
</Typography>
}
</div>

{ !viewMode ? (
<div>
<Button onClick={ (event) => onReject(event, offer) } disabled={assigned || offer.status === 'rejected' || offer.status === 'accepted'} variant="outlined" color="secondary" size={'small'} style={{marginRight: 20}}>
Reject
</Button>
<Button onClick={(event) => onAccept(event, offer)} disabled={assigned || offer.status === 'accepted'} variant="contained" color="primary" size={'small'} style={{marginRight: 20}}>
Accept
</Button>
<Button onClick={(e) => onSendMessage(offer.id)} variant="outlined" color="secondary" size={'small'}>
<MessageIcon fontSize='small' />
</Button>
</div>
) : null }
</div>
}
/>
</ListItem>
<Divider variant="fullWidth" component="li" />
</>
))}
</List>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import React from 'react';
import { FormattedMessage } from 'react-intl';
import { FormControl, Input, InputLabel } from "@material-ui/core";

const EmailInviteInput = ({
onEmailInviteChange
}) => {
return (
<FormControl fullWidth style={{ marginTop: 10, marginBottom: 10 }}>
<InputLabel htmlFor='email-funding-invite'>
<FormattedMessage id='task.funding.email' defaultMessage='Please provide the invitee e-mail' />
</InputLabel>
<Input
id='email'
type='email'
name='email-funding-invite'
onChange={onEmailInviteChange}
/>
</FormControl>
)
}

export default EmailInviteInput;
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
import React from 'react';
import { FormattedMessage } from 'react-intl';
import Introduction from '../../../molecules/introduction/introduction';
import IssueCard from '../../../organisms/issue-card/issue-card';
import SimpleInfo from '../../../molecules/simple-info/simple-info';
import DeliveryDate from '../../../organisms/delivery-date/delivery-date';
import PickupTagList from '../../../molecules/pickup-tag-list/pickup-tag-list';
import PricePlan from '../../../organisms/price-plan/price-plan';
import InputComment from '../../../molecules/input-comment/input-comment';
import OfferDrawerCheckboxes from './offer/offer-drawer-checkboxes';
import InviteInput from './invite/invite-input';
import { makeStyles } from '@material-ui/core';
import CheckboxTerms from '../../../molecules/checkbox-terms/checkbox-terms';

const useStyles = makeStyles(theme => ({
details: {
display: 'flex',
flexDirection: 'column'
},
spanText: {
display: 'inline-block',
verticalAlign: 'middle'
},
}));

interface OfferDrawerCreateProps {
introTitle: any;
introMessage: any;
introImage: any;
issue: any;
simpleInfoText: any;
commentAreaPlaceholder: any;
onDeliveryDateChange: any;
pickupTagListTitle: any;
pickutTagListDescription: any;
setCurrentPrice: any;
currentPrice: any;
onCommentChange: any;
offerCheckboxes: boolean;
onLearnCheckboxChange: any;
onConfirmOfferChange: any;
onTermsCheckboxChange: any;
onEmailInviteChange: any;
hasEmailInput?: boolean;
}

const OfferDrawerCreate: React.FC<OfferDrawerCreateProps> = ({
introTitle,
introMessage,
introImage,
issue,
simpleInfoText,
commentAreaPlaceholder,
onDeliveryDateChange,
pickupTagListTitle,
pickutTagListDescription,
setCurrentPrice,
currentPrice,
onCommentChange,
offerCheckboxes,
onLearnCheckboxChange,
onConfirmOfferChange,
onTermsCheckboxChange,
onEmailInviteChange,
hasEmailInput = false
}) => {

const classes = useStyles();

return (
<>
<Introduction
title={introTitle}
image={introImage}
>
<span className={classes.spanText}>
{introMessage}
</span>
</Introduction>
<IssueCard issue={issue} />
<SimpleInfo text={
simpleInfoText
} />
{hasEmailInput && <InviteInput onEmailInviteChange={onEmailInviteChange} />}
<DeliveryDate
date={issue.data.deadline}
onDateChange={onDeliveryDateChange}
/>
<PickupTagList
primaryText={
pickupTagListTitle
}
secondaryText={
pickutTagListDescription
}
onPickItem={(price) => setCurrentPrice(price)}
/>
<PricePlan plan={
{
fee: 8,
category: <FormattedMessage id='actions.task.payment.plan.opensource' defaultMessage='Open Source' />,
title: <FormattedMessage id='actions.task.payment.plan.opensource.info' defaultMessage='For Open Source Project' />,
items: [
<FormattedMessage id='actions.task.payment.plan.bullet.public' defaultMessage='For Public Projects' />,
<FormattedMessage id='actions.task.payment.plan.bullet.basic' defaultMessage='Basic Campaign' />,
],
}
} price={currentPrice} onChange={(price) => setCurrentPrice(price)} />
<InputComment
placeholder={commentAreaPlaceholder}
onChange={onCommentChange}
/>
{offerCheckboxes &&
<OfferDrawerCheckboxes
currentPrice={currentPrice}
onLearnCheckboxChange={onLearnCheckboxChange}
onConfirmOfferChange={onConfirmOfferChange}
/>
}
<CheckboxTerms
onAccept={onTermsCheckboxChange}
/>
</>
);
};

export default OfferDrawerCreate;
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import React, { useState } from 'react';
import { Tab, Tabs } from "@material-ui/core";


const OfferDrawerTabs = ({ tabs, onTabChange }) => {
const [tabValue, setTabValue] = useState(0)

const handleChange = (event, newValue) => {
setTabValue(newValue)
onTabChange(newValue)
}

return (
<>
<Tabs
value={tabValue}
onChange={handleChange}
indicatorColor='secondary'
textColor='secondary'
>
{tabs.map((tab) => <Tab label={tab.label} value={tab.value} />)}
</Tabs>
{tabs.map((tab) => tab.value === tabValue && tab.component)}
</>
);
}

export default OfferDrawerTabs;
Original file line number Diff line number Diff line change
Expand Up @@ -58,3 +58,21 @@ Primary.args = {
}
}
};

export const WithTabs = Template.bind({});
WithTabs.args = {
...Primary.args,
offers: [
{
User: {
username: 'username',
picture_url: 'https://via.placeholder.com/150',
name: 'name',
},
status: 'status',
value: 100,
suggestedDate: new Date(),
},
],
tabs: true,
};
Loading