Skip to content

Commit

Permalink
Add Vote Proposal card layout
Browse files Browse the repository at this point in the history
  • Loading branch information
baomastr committed May 30, 2022
1 parent 7937cac commit 235757a
Show file tree
Hide file tree
Showing 10 changed files with 460 additions and 2 deletions.
10 changes: 8 additions & 2 deletions src/components/v2/Icon/icons/check.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,18 @@ import * as React from 'react';
import { SVGProps } from 'react';

const SvgCheck = (props: SVGProps<SVGSVGElement>) => (
<svg viewBox="0 0 65 64" fill="none" xmlns="http://www.w3.org/2000/svg" {...props}>
<svg
viewBox="0 0 65 64"
fill="none"
xmlns="http://www.w3.org/2000/svg"
strokeWidth={4}
{...props}
>
<circle cx={32.5} cy={32} r={24} fill="currentColor" />
<path
d="m41.5 26-12 12-6-6"
stroke="#fff"
strokeWidth={4}
strokeWidth="inherit"
strokeLinecap="round"
strokeLinejoin="round"
/>
Expand Down
19 changes: 19 additions & 0 deletions src/components/v2/Icon/icons/dots.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import * as React from 'react';
import { SVGProps } from 'react';

const SvgDots = (props: SVGProps<SVGSVGElement>) => (
<svg
width="21"
height="4"
viewBox="0 0 21 4"
fill="none"
xmlns="http://www.w3.org/2000/svg"
{...props}
>
<circle cx="10.5" cy="2" r="2" fill="currentColor" />
<circle cx="18.5" cy="2" r="2" fill="currentColor" />
<circle cx="2.5" cy="2" r="2" fill="currentColor" />
</svg>
);

export default SvgDots;
11 changes: 11 additions & 0 deletions src/components/v2/Icon/icons/exclamation.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import * as React from 'react';
import { SVGProps } from 'react';

const SvgExclamation = (props: SVGProps<SVGSVGElement>) => (
<svg viewBox="0 0 3 18" fill="none" xmlns="http://www.w3.org/2000/svg" {...props}>
<circle cx="1.5" cy="16.5" r="1.5" fill="currentColor" />
<rect x="0.5" width="2" height="12" rx="1" fill="currentColor" />
</svg>
);

export default SvgExclamation;
2 changes: 2 additions & 0 deletions src/components/v2/Icon/icons/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ export { default as checkInline } from './checkInline';
export { default as mark } from './mark';
export { default as arrowShaft } from './arrowShaft';
export { default as notice } from './notice';
export { default as dots } from './dots';
export { default as exclamation } from './exclamation';

// Coin icons
export { default as aave } from './coins/aave';
Expand Down
53 changes: 53 additions & 0 deletions src/components/v2/VoteProposalUi/index.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import React from 'react';
import { withThemeProvider, withCenterStory } from 'stories/decorators';
import { VoteProposalUi } from '.';

export default {
title: 'Components/VoteProposalUi',
decorators: [withThemeProvider, withCenterStory({ width: 750 })],
parameters: {
backgrounds: {
default: 'Default',
},
},
};

export const Active = () => (
<VoteProposalUi
proposalNumber={58}
proposalText="Buy back and burn and Tokenomic contribution finised soon"
proposalStatus="active"
votedFor="2130.02 XVS"
votedAgainst="2130.02 XVS"
abstain="100 XVS"
voteStatus="votedFor"
/>
);
export const Queued = () => (
<VoteProposalUi
proposalNumber={58}
proposalText="Buy back and burn and Tokenomic contribution finised soon"
proposalStatus="queued"
/>
);
export const ReadyToExecute = () => (
<VoteProposalUi
proposalNumber={58}
proposalText="Buy back and burn and Tokenomic contribution finised soon"
proposalStatus="readyToExecute"
/>
);
export const Executed = () => (
<VoteProposalUi
proposalNumber={58}
proposalText="Buy back and burn and Tokenomic contribution finised soon"
proposalStatus="executed"
/>
);
export const Cancelled = () => (
<VoteProposalUi
proposalNumber={58}
proposalText="Buy back and burn and Tokenomic contribution finised soon"
proposalStatus="cancelled"
/>
);
205 changes: 205 additions & 0 deletions src/components/v2/VoteProposalUi/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,205 @@
/** @jsxImportSource @emotion/react */
import React, { useMemo } from 'react';
import Paper from '@mui/material/Paper';
import Grid from '@mui/material/Grid';
import Typography from '@mui/material/Typography';

import { useTranslation } from 'translation';
import { Icon } from '../Icon';
import { ProgressBar } from '../ProgressBar';
import { useStyles } from './styles';

type ProposalStatus = 'active' | 'queued' | 'readyToExecute' | 'executed' | 'cancelled';

interface IStatusCard {
status: ProposalStatus;
votedFor?: string;
votedAgainst?: string;
abstain?: string;
}

const StatusCard: React.FC<IStatusCard> = ({ status, votedFor, votedAgainst, abstain }) => {
const styles = useStyles();
const { t } = useTranslation();

switch (status) {
case 'active':
return (
<>
<div css={styles.voteRow}>
<Typography variant="small2" color="textPrimary">
{t('voteProposalUi.statusCard.for')}
</Typography>

<Typography variant="small2" color="textPrimary">
{votedFor}
</Typography>
</div>
<ProgressBar value={20} step={1} ariaLabel="progress" min={1} max={100} />

<div css={styles.voteRow}>
<Typography variant="small2" color="textPrimary">
{t('voteProposalUi.statusCard.against')}
</Typography>

<Typography variant="small2" color="textPrimary">
{votedAgainst}
</Typography>
</div>
<ProgressBar value={20} step={1} ariaLabel="progress" min={1} max={100} />

<div css={styles.voteRow}>
<Typography variant="small2" color="textPrimary">
{t('voteProposalUi.statusCard.abstain')}
</Typography>

<Typography variant="small2" color="textPrimary">
{abstain}
</Typography>
</div>
<ProgressBar value={5} step={1} ariaLabel="progress" min={1} max={100} />
</>
);
case 'queued':
return (
<>
<div css={[styles.iconWrapper, styles.iconDotsWrapper]}>
<Icon css={styles.icon} name="dots" />
</div>
<Typography css={styles.statusText} variant="body2">
{t('voteProposalUi.statusCard.queued')}
</Typography>
</>
);
case 'readyToExecute':
return (
<>
<div css={[styles.iconWrapper, styles.iconInfoWrapper]}>
<Icon css={styles.icon} name="exclamation" />
</div>
<Typography css={styles.statusText} variant="body2">
{t('voteProposalUi.statusCard.readyToExecute')}
</Typography>
</>
);
case 'executed':
return (
<>
<div css={[styles.iconWrapper, styles.iconMarkWrapper]}>
<Icon css={[styles.icon, styles.iconCheck]} name="mark" />
</div>
<Typography css={styles.statusText} variant="body2">
{t('voteProposalUi.statusCard.executed')}
</Typography>
</>
);
default:
case 'cancelled':
return (
<>
<div css={[styles.iconWrapper, styles.iconCloseWrapper]}>
<Icon css={styles.icon} name="close" />
</div>
<Typography css={styles.statusText} variant="body2">
{t('voteProposalUi.statusCard.cancelled')}
</Typography>
</>
);
}
};

type VoteStatus = 'votedFor' | 'votedAgainst' | 'abstained';

interface IVoteProposalUiProps {
className?: string;
proposalNumber: number;
proposalText: string;
proposalStatus: ProposalStatus;
voteStatus?: VoteStatus;
votedFor?: string;
votedAgainst?: string;
abstain?: string;
}

export const VoteProposalUi: React.FC<IVoteProposalUiProps> = ({
className,
proposalNumber,
proposalText,
proposalStatus,
voteStatus,
votedFor,
votedAgainst,
abstain,
}) => {
const styles = useStyles();
const { t } = useTranslation();

const voteStatusText = useMemo(() => {
switch (voteStatus) {
case 'votedFor':
return t('voteProposalUi.voteStatus.votedFor');
case 'votedAgainst':
return t('voteProposalUi.voteStatus.votedAgainst');
case 'abstained':
return t('voteProposalUi.voteStatus.abstained');
default:
return t('voteProposalUi.voteStatus.notVoted');
}
}, [voteStatus]);

return (
<Paper className={className} css={styles.root}>
<Grid container>
<Grid css={[styles.gridItem, styles.gridItemLeft]} item xs={12} sm={8}>
<div css={styles.cardHeader}>
<div css={styles.cardBadges}>
<Typography
variant="small2"
color="textPrimary"
css={[styles.cardBadgeItem, styles.cardBadgeNumber]}
>
#{proposalNumber}
</Typography>
{proposalStatus === 'active' && (
<Typography
variant="small2"
color="textPrimary"
css={[styles.cardBadgeItem, styles.cardBadgeActive]}
>
{t('voteProposalUi.proposalStatus.active')}
</Typography>
)}
</div>

<Typography variant="small2">{voteStatusText}</Typography>
</div>

<Typography variant="h4" css={styles.cardTitle}>
{proposalText}
</Typography>

<div css={styles.cardFooter}>
<Typography variant="small2">
{t('voteProposalUi.activeUntil')}
<Typography variant="small2" color="textPrimary">
27 Jun 13:54
</Typography>
</Typography>

<Typography color="textPrimary" variant="small2">
27h : 13m : 54s
</Typography>
</div>
</Grid>
<Grid css={[styles.gridItem, styles.gridItemRight]} item xs={12} sm={4}>
<StatusCard
status={proposalStatus}
votedFor={votedFor}
votedAgainst={votedAgainst}
abstain={abstain}
/>
</Grid>
</Grid>
</Paper>
);
};
Loading

1 comment on commit 235757a

@github-actions
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Coverage report

St.
Category Percentage Covered / Total
🔴 Statements 39.09% 1790/4579
🔴 Branches 32.37% 695/2147
🔴 Functions 33.65% 463/1376
🔴 Lines 39.64% 1758/4435

Test suite run success

175 tests passing in 65 suites.

Report generated by 🧪jest coverage report action from 235757a

Please sign in to comment.