Skip to content
This repository has been archived by the owner on Feb 23, 2022. It is now read-only.

(CEM-2514) MenuItemCard Component #383

Open
wants to merge 15 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 3 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
10 changes: 9 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,12 @@ node_modules
.awcache
dist
.idea
debug.log
debug.log
src/Containers/HorizontalScrollList/HorizontalScrollList.tsx
src/Containers/MiddleCanvas/DroppableElement.tsx
Copy link
Member

Choose a reason for hiding this comment

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

Why is this in gitignore??

src/Containers/Modal/Modal.tsx
src/Containers/QuestionMarkHover/QuestionMarkHover.stories.tsx
src/Containers/QuestionMarkHover/QuestionMarkHover.tsx
src/Containers/SelectList/SelectList.tsx
src/Fragments/InputFragment.tsx
src/Inputs/Button/Button.tsx
16 changes: 16 additions & 0 deletions src/Containers/LimitedTimeBanner/LimitedTimeBanner.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import React from 'react';
import { Meta, Story } from '@storybook/react';
import { LimitedTimeBanner,LimitedTimeBannerProps} from '../../index';
import { createStoryTitle} from '../../Constants';

export default {
title: createStoryTitle('LimitedTimeBanner'),
component: LimitedTimeBanner,
args: {
HoursRemaining: '2 Hours Remaining'
},
} as Meta;

export const Basic: Story<LimitedTimeBannerProps> = (args) => (
<LimitedTimeBanner {...args}/>
);
41 changes: 41 additions & 0 deletions src/Containers/LimitedTimeBanner/LimitedTimeBanner.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import React from 'react';
import styled from 'styled-components';
import {Clock} from '@styled-icons/bootstrap/Clock';
import { MainInterface} from '@Utils/BaseStyles';

export interface LimitedTimeBannerProps
extends MainInterface {
HoursRemaining: number,
}

export const LimitedTimeBanner: React.FC<LimitedTimeBannerProps> = ({
HoursRemaining,...props
}): React.ReactElement => (
<BannerBox {...props}>
<Icon />
<p>{HoursRemaining} Hours Remaining</p>
</BannerBox>
) ;

const BannerBox = styled.div`
// Theme Stuff
${({theme}):string => `
font-family: ${theme.font.family};
color: ${theme.colors.background}};
`}
background-color: rgba(0,0,0,0.5);
font-size: 25px;
text-align: center;
width: 350px;
height: 40px;
`;

const Icon = styled(Clock)`
width: 25px;
float: left;
padding-top:5px;
padding-bottom:5px;
padding-left: 5px;
`;

export default LimitedTimeBanner;
20 changes: 20 additions & 0 deletions src/Containers/LoyaltyPoints/LoyaltyPoints.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import React from 'react';
import { Meta, Story } from '@storybook/react';
import { LoyaltyPointsProps, LoyaltyPoints } from "../../index";
import { createStoryTitle } from '../../Constants';

export default {

title: createStoryTitle('LoyaltyPoints'),
component: LoyaltyPoints,
args:{
amount: '+10★'
}
}as Meta;


export const Basic: Story<LoyaltyPointsProps> = (args) => (
<LoyaltyPoints {...args}/>
)

// todo switch star from text to icon using styled-icons import
31 changes: 31 additions & 0 deletions src/Containers/LoyaltyPoints/LoyaltyPoints.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import React from 'react';
import styled from 'styled-components';
import { MainInterface } from '@Utils/BaseStyles'

export const LoyaltyPoints: React.FC<LoyaltyPointsProps> = ({
amount, ...props
}):React.ReactElement => <LoyaltyPointsBox {...props}><p>{amount}</p></LoyaltyPointsBox>;

export interface LoyaltyPointsProps
extends MainInterface{
amount: string;
}

const LoyaltyPointsBox = styled.div`

${({theme}):string => `
font-family: ${theme.font.family};
font-size: 20px;
width: 60px;
height: 30px;
padding: 5px -10px;
border-radius:50px;
border-bottom-left-radius: 0px;
border-top-left-radius: 0px;
background-color: ${theme.colors.background};
text-align: center;
color: ${theme.colors.loyaltyText};

`}

`
39 changes: 39 additions & 0 deletions src/Containers/MenuItemCard/MenuItemCard.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import React from 'react';
import { Meta, Story } from '@storybook/react';
import { MenuItemCard, MenuItemCardProps, LoyaltyPoints, LimitedTimeBanner, SaleTag} from '../../index';
import { createStoryTitle } from '../../Constants';

export default {
title: createStoryTitle('MenuItemCard'),
component: MenuItemCard,
subcomponents: {LoyaltyPoints, LimitedTimeBanner, SaleTag},
argTypes: { onClick: { action: 'Link to next step' } },
args: {
animated: true,
flat: false,
widthFitContent: false,
sale: false,
soldOut: false,
loyaltyPointsToggle: true,
limitedTimeBannerToggle: true,
saleTagToggle: true,
ItemImage: 'https://keyassets-p2.timeincuk.net/wp/prod/wp-content/uploads/sites/63/2007/09/Ricotta-cheese-pancakes-with-blackberry-butter.jpg',
ItemName: 'Blackberry Pancakes',
ItemPrice: 14.99,
discountAmount: 3,
LoyaltyPoints: (
<LoyaltyPoints loyaltyAmount={10}/>
),
LimitedTimeBanner:(
<LimitedTimeBanner HoursRemaining= {3}/>
),
SaleTag: (
<SaleTag saleTagAmount={5}/>
),
},
} as Meta;

export const Basic: Story<MenuItemCardProps> = (args) => <MenuItemCard {...args}> <LoyaltyPoints loyaltyAmount={0} {...args}/>
<LimitedTimeBanner HoursRemaining={0} {...args}/> <SaleTag {...args} /> </MenuItemCard>;


139 changes: 139 additions & 0 deletions src/Containers/MenuItemCard/MenuItemCard.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
import React from 'react';
import styled from 'styled-components';
import { Main, MainInterface, Responsive, ResponsiveInterface } from '@Utils/BaseStyles';
import { transition, } from '@Utils/Mixins';
import { Container } from '@Containers/FileUpload/StyledComponents';
// eslint-disable-next-line import/no-cycle
import { Heading } from '../../index';

export const ItemCard: React.FC<MenuItemCardProps> = ({
children,
...props
}): React.ReactElement => <MenuItemCardBox {...props}>{children}</MenuItemCardBox>;

export interface MenuItemCardProps
extends MainInterface, ResponsiveInterface, React.HTMLAttributes<HTMLDivElement> {

LoyaltyPoints: React.ReactElement;
LimitedTimeBanner: React.ReactElement;
SaleTag: React.ReactElement;
animated?: boolean;
flat?: boolean;
widthFitContent?: boolean;
sale?: boolean;
soldOut?: boolean;
loyaltyPointsToggle?: boolean;
limitedTimeBannerToggle?: boolean,
saleTagToggle?: boolean,
saleTagAmount: number,
ItemImage: string,
ItemName: string,
ItemPrice: number,
discountAmount: number,
}

export const MenuItemCard: React.FC<MenuItemCardProps> = ({
// eslint-disable-next-line @typescript-eslint/no-shadow
LoyaltyPoints,
LimitedTimeBanner,
SaleTag,
animated,
flat,
widthFitContent,
sale,
soldOut,
saleTagAmount,
loyaltyPointsToggle,
limitedTimeBannerToggle,
saleTagToggle,
ItemImage,
ItemName,
ItemPrice,
discountAmount,
...props

}): React.ReactElement => (
<ItemCard {...props} ItemImage={ItemImage} ItemName={ItemName} ItemPrice={ItemPrice} discountAmount={discountAmount} animated={animated}
flat={flat} widthFitContent={widthFitContent} sale={sale} soldOut={soldOut} LoyaltyPoints = {LoyaltyPoints} saleTagAmount = {saleTagAmount}
loyaltyPointsToggle={loyaltyPointsToggle} LimitedTimeBanner = {LimitedTimeBanner} SaleTag = {SaleTag} saleTagToggle = {saleTagToggle}
limitedTimeBannerToggle={limitedTimeBannerToggle}>

<img src={ItemImage} alt={ItemName} style={{ width: 350, height: 200 }} />
<Heading bold>{ItemName}</Heading>

{ limitedTimeBannerToggle && <Container><LimitedTimeBannerPosition>{LimitedTimeBanner}</LimitedTimeBannerPosition></Container> }
{ saleTagToggle && <Container><SaleTagPosition>{SaleTag}</SaleTagPosition></Container>}
{ loyaltyPointsToggle && <Container><LoyaltyPointsPosition>{LoyaltyPoints}</LoyaltyPointsPosition></Container> }

{ sale?
<>
<SalePropsSlash>{ItemPrice}</SalePropsSlash>
<OnSale>{ItemPrice - saleTagAmount}</OnSale>
</>
:
<SaleProps>{ItemPrice}</SaleProps>
}

</ItemCard>
);

const MenuItemCardBox = styled.div<MenuItemCardProps & MainInterface & ResponsiveInterface>`
position: relative;
background-color: white;
width: 350px;
height: 350px;

${({ theme, ...props }): string => `
border-radius: ${theme.dimensions.radius};
font-family: ${theme.font.family};
padding: ${theme.dimensions.padding.container};

${Main({
...props,
})} `}

box-shadow: ${({ flat, theme }): string => theme.depth[flat ? 0 : 1]};

${({ animated, flat, theme }): string =>
animated ? ` ${transition(['box-shadow'])} &:hover {
box-shadow: ${theme.depth[flat ? 1 : 2]};
}` : ''}

${Responsive}

${({ soldOut }) =>
soldOut && `
opacity: 0.5;
cursor: not-allowed; `}

${({ widthFitContent }): string => `${widthFitContent ? 'width:fit-content;' : ''} `}
`;

const SaleProps = styled.header`
font-size: 30px;
text-align: right;
`
const OnSale = styled.header`
font-size: 40px;
text-align: right;
font-weight: bold;
color: #EE2434;
`
const SalePropsSlash = styled(SaleProps)`
text-decoration: line-through;
font-size: 25px;
opacity: .6;
`
const LoyaltyPointsPosition = styled.div`
position: absolute;
top: 30px;
`
const LimitedTimeBannerPosition = styled.div`
position: absolute;
bottom: 150px;
`
const SaleTagPosition = styled.div`
position: absolute;
right: 20px;
top: 30px;
`
16 changes: 16 additions & 0 deletions src/Containers/SaleTag/SaleTag.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import React from 'react';
import { Meta, Story } from '@storybook/react';
import { SaleTag, SaleTagProps } from '../../index';
import { createStoryTitle } from '../../Constants';

export default {
title: createStoryTitle('SaleTag'),
component: SaleTag,
args: {
saleAmount: 2,
},
} as Meta;

export const Basic: Story<SaleTagProps> = (args) => (
<SaleTag {...args}/>
);
37 changes: 37 additions & 0 deletions src/Containers/SaleTag/SaleTag.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import React from 'react';
import styled from 'styled-components';

export interface SaleTagProps extends React.HTMLAttributes<HTMLSpanElement> {
saleAmount: number;
}

export const SaleTag: React.FC<SaleTagProps> = ({
saleAmount = 2,
...props
}): React.ReactElement => (
<SaleTagDiv {...props} saleAmount={saleAmount}>
{saleAmount}$ off
</SaleTagDiv>
);

const SaleTagDiv = styled.span<SaleTagProps>`
${({theme, ...props}):string => `
border-radius: 100px;
width: 100px;
height: 40px;
padding-left: 10px;
padding-right: 10px;
padding-top: 3px;
padding-bottom: 3px;
border-style: solid;
border-width: 1px;
font-size: 15px;

background-color: ${theme.colors.background};
color: ${theme.colors.primary};
border-color: ${theme.colors.border};
font-family: ${theme.font.family};
font-weight: bolder;
text-align: center;
`}
`;
6 changes: 6 additions & 0 deletions src/Containers/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,3 +76,9 @@ export * from './EditDraggableCanvas/_DraggableTable';
export * from './InviteComponent/Invite';
export * from './SeatingInfoInput/SeatingInfoInput';
export * from './PartyInfoInput/PartyInfoInput';
// eslint-disable-next-line import/no-cycle
export * from './MenuItemCard/MenuItemCard'
// eslint-disable-next-line import/no-cycle
export * from './LimitedTimeBanner/LimitedTimeBanner'
export * from './LoyaltyPoints/LoyaltyPoints'
export * from './SaleTag/SaleTag'
Loading