Skip to content

Commit

Permalink
feat: marketplace (#184)
Browse files Browse the repository at this point in the history
* feat: marketplace

* feat: marketplace + api integration

* feat: marketplace flow

* feat: marketplace api integration refactor

* feat: error handling and git validations

* fix: marketplace notification
  • Loading branch information
CristhianF7 authored May 23, 2023
1 parent 37b9c9f commit c11e9d8
Show file tree
Hide file tree
Showing 53 changed files with 1,200 additions and 516 deletions.
2 changes: 1 addition & 1 deletion components/card/card.styled.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import styled, { css } from 'styled-components';
import { CardProps } from '.';

export const CardContainer = styled.div<CardProps>`
border: 2px solid #e2e8f0;
border: 2px solid ${({ theme }) => theme.colors.pastelLightBlue};
border-radius: 8px;
background-color: white;
cursor: pointer;
Expand Down
2 changes: 1 addition & 1 deletion components/checkbox/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ const Checkbox = forwardRef<HTMLInputElement, CheckboxProps>(function Checkbox(p
<CheckboxMUI
{...props}
inputRef={ref}
style={{ border: '1px' }}
style={{ border: '1px', padding: 0 }}
icon={
<CheckBoxOutlineBlankIcon
sx={{ borderRadius: '4px', color: props.disabled ? `${QUARTZ}` : `${SPUN_PEARL}` }}
Expand Down
11 changes: 11 additions & 0 deletions components/errorBanner/errorBanner.styled.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,18 @@ export const Container = styled.div`
width: calc(100% - 32px);
`;

export const ErrorContainer = styled.div`
display: flex;
flex-direction: column;
`;

export const Header = styled.div`
display: flex;
gap: 8px;
`;

export const List = styled.ul`
padding-left: 28px;
`;

export const ListItem = styled.li``;
32 changes: 26 additions & 6 deletions components/errorBanner/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,41 @@ import ErrorIcon from '@mui/icons-material/Error';
import Typography from '../typography';
import { VOLCANIC_SAND } from '../../constants/colors';

import { Container, Header } from './errorBanner.styled';
import { Container, ErrorContainer, Header, List, ListItem } from './errorBanner.styled';

export interface ErrorBannerProps {
details?: string;
text: string;
error: Array<string> | string;
}

const ErrorBanner: FunctionComponent<ErrorBannerProps> = ({ text }) => {
const ErrorBanner: FunctionComponent<ErrorBannerProps> = ({ error }) => {
const isErrorArray = Array.isArray(error) && error.length > 1;
return (
<Container>
<Header>
<ErrorIcon color="error" fontSize="small" />
<Typography variant="body2" color={VOLCANIC_SAND}>
<div dangerouslySetInnerHTML={{ __html: text }} />
</Typography>
<ErrorContainer>
{isErrorArray ? (
<>
<Typography variant="body2" color={VOLCANIC_SAND}>
<strong>Error</strong>
</Typography>
<List>
{error.map((errorItem) => (
<ListItem key={errorItem}>
<Typography variant="body2" color={VOLCANIC_SAND}>
<div dangerouslySetInnerHTML={{ __html: errorItem }} />
</Typography>
</ListItem>
))}
</List>
</>
) : (
<Typography variant="body2" color={VOLCANIC_SAND}>
<div dangerouslySetInnerHTML={{ __html: `<strong>Error </strong>${error}` }} />
</Typography>
)}
</ErrorContainer>
</Header>
</Container>
);
Expand Down
2 changes: 1 addition & 1 deletion components/gitProviderButton/gitProviderButton.styled.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ export const Button = styled.button<{ active?: boolean }>`
align-items: center;
width: 260px;
height: 84px;
border: 2px solid #e2e8f0;
border: 2px solid ${({ theme }) => theme.colors.pastelLightBlue};
border-radius: 8px;
background-color: white;
cursor: pointer;
Expand Down
4 changes: 2 additions & 2 deletions components/installationStepContainer/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ const InstallationStepContainer: FunctionComponent<InstallationStepContainerProp
children,
...rest
}) => {
const { completedSteps, isProvisioned } = useAppSelector(({ cluster }) => ({
...cluster,
const { completedSteps, isProvisioned } = useAppSelector(({ api }) => ({
...api,
}));
const progress = useMemo(() => {
const clusterChecks = Object.keys(CLUSTER_CHECKS);
Expand Down
50 changes: 50 additions & 0 deletions components/marketplaceCard/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import React, { FunctionComponent, PropsWithChildren } from 'react';
import Image from 'next/image';

import Tag from '../tag';
import { MarketplaceApp } from '../../types/marketplace';
import Button from '../../components/button';
import Typography from '../typography';
import { VOLCANIC_SAND } from '../../constants/colors';

import { Card, Description, Header } from './marketplaceCard.styled';

export interface MarketplaceCardProps extends MarketplaceApp {
onClick?: () => void;
showSubmitButton?: boolean;
}

const MarketplaceCard: FunctionComponent<PropsWithChildren<MarketplaceCardProps>> = ({
name,
categories,
image_url,
description,
onClick,
showSubmitButton = true,
children,
}) => {
return (
<Card>
<Header>
<Image alt={name} height={28} width={28} src={image_url} style={{ objectFit: 'contain' }} />
<Typography
variant="buttonSmall"
sx={{ textTransform: 'capitalize' }}
color={VOLCANIC_SAND}
>
{name}
</Typography>
{categories &&
categories.map((category) => <Tag key={category} text={category} bgColor="purple" />)}
</Header>
<Description variant="body2">{description || children}</Description>
{showSubmitButton && (
<Button variant="outlined" color="secondary" onClick={onClick}>
Add
</Button>
)}
</Card>
);
};

export default MarketplaceCard;
33 changes: 33 additions & 0 deletions components/marketplaceCard/marketplaceCard.styled.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import styled from 'styled-components';

import Typography from '../../components/typography';

export const Card = styled.div`
background-color: ${({ theme }) => theme.colors.white};
border: 1px solid ${({ theme }) => theme.colors.pastelLightBlue};
border-radius: 12px;
height: 194px;
padding: 24px;
width: 372px;
`;

export const Description = styled(Typography)`
color: ${({ theme }) => theme.colors.saltboxBlue};
height: 100px;
margin: 16px 0;
& a {
color: ${({ theme }) => theme.colors.primary};
text-decoration: none;
}
& a:hover {
text-decoration: underline;
}
`;

export const Header = styled.div`
align-items: center;
display: flex;
gap: 16px;
`;
86 changes: 86 additions & 0 deletions components/marketplaceModal/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
import React, { FunctionComponent } from 'react';
import { Box, Divider } from '@mui/material';
import Image from 'next/image';
import { Control } from 'react-hook-form';

import Modal from '../modal';
import Button from '../button';
import Typography from '../typography';
import ControlledPassword from '../controlledFields/Password';
import { MarketplaceApp } from '../../types/marketplace';
import { BISCAY, SALTBOX_BLUE } from '../../constants/colors';

import { Content, Close, Footer, Header } from './marketplaceModal.styled';

export interface MarketplaceModalProps extends MarketplaceApp {
control: Control;
isOpen: boolean;
isValid: boolean;
closeModal: () => void;
onSubmit: (app: MarketplaceApp) => void;
}

const MarketplaceModal: FunctionComponent<MarketplaceModalProps> = ({
control,
closeModal,
isOpen,
isValid,
name,
image_url,
secret_keys,
onSubmit,
...rest
}) => {
const handleSubmit = () => {
onSubmit({ name, image_url, secret_keys, ...rest });
};

return (
<Modal isOpen={isOpen} padding={0}>
<Box
sx={{
width: '630px',
height: 'auto',
backgroundColor: 'white',
borderRadius: '8px',
boxShadow: '0px 2px 4px rgba(100, 116, 139, 0.1)',
}}
>
<Header>
<Image alt={name} src={image_url} width={30} height={30} />
<Typography variant="h6" color={BISCAY}>
{name}
</Typography>
<Close onClick={closeModal} htmlColor={SALTBOX_BLUE} fontSize="medium" />
</Header>
<Divider />
<Content>
{secret_keys &&
secret_keys.map(({ label, name }) => (
<ControlledPassword
key={label}
control={control}
name={name}
label={label}
rules={{
required: true,
}}
required
/>
))}
</Content>
<Divider />
<Footer>
<Button variant="text" color="info" onClick={closeModal}>
Cancel
</Button>
<Button variant="contained" color="primary" disabled={!isValid} onClick={handleSubmit}>
Add
</Button>
</Footer>
</Box>
</Modal>
);
};

export default MarketplaceModal;
32 changes: 32 additions & 0 deletions components/marketplaceModal/marketplaceModal.styled.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import styled from 'styled-components';
import CloseIcon from '@mui/icons-material/Close';

export const Content = styled.div`
display: flex;
flex-direction: column;
gap: 24px;
padding: 32px 24px;
`;

export const Close = styled(CloseIcon)`
cursor: pointer;
position: fixed;
top: 25px;
right: 25px;
`;

export const Footer = styled.div`
display: flex;
gap: 16px;
justify-content: flex-end;
padding: 16px 24px;
width: calc(100% - 48px);
`;

export const Header = styled.div`
display: flex;
gap: 16px;
padding: 24px;
position: relative;
text-transform: capitalize;
`;
3 changes: 2 additions & 1 deletion components/menu/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import Typography from '../typography';
import { VOLCANIC_SAND } from '../../constants/colors';

export interface MenuProps {
isDisabled: boolean;
isDisabled?: boolean;
label: string | ReactNode;
options?: Array<{
label: string;
Expand Down Expand Up @@ -44,6 +44,7 @@ const Menu: FunctionComponent<MenuProps> = ({ isDisabled, label, options, onClic
onClick={handleClick}
disableRipple
disabled={isDisabled}
sx={{ padding: 0 }}
>
{label}
</Button>
Expand Down
7 changes: 5 additions & 2 deletions components/modal/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ const style = {
transform: 'translate(-50%, -50%)',
width: 'auto',
borderRadius: '8px',
p: 4,
zIndex: 2000,
};

Expand All @@ -19,6 +18,7 @@ export interface IModalProps {
children: React.ReactElement;
isOpen: boolean;
onCloseModal?: () => void;
padding?: number;
}

const Modal: FunctionComponent<IModalProps> = ({
Expand All @@ -27,6 +27,7 @@ const Modal: FunctionComponent<IModalProps> = ({
children,
isOpen,
onCloseModal,
padding = 4,
}) => (
<ModalMui
open={isOpen}
Expand All @@ -35,7 +36,9 @@ const Modal: FunctionComponent<IModalProps> = ({
aria-describedby="modal-description"
sx={{ zIndex: 2000 }}
>
<Box sx={{ ...style, backgroundColor, boxShadow: boxShadow && 24 }}>{children}</Box>
<Box sx={{ ...style, p: padding, backgroundColor, boxShadow: boxShadow ? 24 : 0 }}>
{children}
</Box>
</ModalMui>
);

Expand Down
Loading

0 comments on commit c11e9d8

Please sign in to comment.