Skip to content

Commit

Permalink
Merge pull request #32339 from software-mansion-labs/wave8/create-a-w…
Browse files Browse the repository at this point in the history
…orkspace-card

[Wave8] Create a Workspace Card
  • Loading branch information
mountiny authored Dec 20, 2023
2 parents 9ea6b39 + 0ea0c16 commit 249096e
Show file tree
Hide file tree
Showing 10 changed files with 127 additions and 30 deletions.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion src/components/DatePicker/CalendarPicker/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,7 @@ class CalendarPicker extends React.PureComponent {
<View
style={[
this.props.themeStyles.calendarDayContainer,
isSelected ? this.props.themeStyles.calendarDayContainerSelected : {},
isSelected ? this.props.themeStyles.buttonDefaultBG : {},
!isDisabled ? this.props.StyleUtils.getButtonBackgroundColorStyle(getButtonState(hovered, pressed)) : {},
]}
>
Expand Down
2 changes: 2 additions & 0 deletions src/components/Icon/Illustrations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import ConciergeNew from '@assets/images/simple-illustrations/simple-illustratio
import CreditCardsNew from '@assets/images/simple-illustrations/simple-illustration__credit-cards.svg';
import EmailAddress from '@assets/images/simple-illustrations/simple-illustration__email-address.svg';
import HandEarth from '@assets/images/simple-illustrations/simple-illustration__handearth.svg';
import HotDogStand from '@assets/images/simple-illustrations/simple-illustration__hotdogstand.svg';
import InvoiceBlue from '@assets/images/simple-illustrations/simple-illustration__invoice.svg';
import LockOpen from '@assets/images/simple-illustrations/simple-illustration__lockopen.svg';
import Luggage from '@assets/images/simple-illustrations/simple-illustration__luggage.svg';
Expand All @@ -60,6 +61,7 @@ export {
ConciergeExclamation,
CreditCardsBlue,
EmailAddress,
HotDogStand,
InvoiceOrange,
JewelBoxBlue,
JewelBoxGreen,
Expand Down
2 changes: 1 addition & 1 deletion src/components/MenuItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -531,7 +531,7 @@ function MenuItem(
{badgeText && (
<Badge
text={badgeText}
badgeStyles={[styles.alignSelfCenter, brickRoadIndicator ? styles.mr2 : undefined, focused || isHovered || pressed ? styles.hoveredButton : {}]}
badgeStyles={[styles.alignSelfCenter, brickRoadIndicator ? styles.mr2 : undefined, focused || isHovered || pressed ? styles.buttonHoveredBG : {}]}
/>
)}
{/* Since subtitle can be of type number, we should allow 0 to be shown */}
Expand Down
40 changes: 40 additions & 0 deletions src/components/Section/IconSection.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import PropTypes from 'prop-types';
import React from 'react';
import {View} from 'react-native';
import Icon from '@components/Icon';
import useThemeStyles from '@hooks/useThemeStyles';

const iconSectionPropTypes = {
icon: PropTypes.icon,
IconComponent: PropTypes.IconComponent,
iconContainerStyles: PropTypes.iconContainerStyles,
};

const defaultIconSectionPropTypes = {
icon: null,
IconComponent: null,
iconContainerStyles: [],
};

function IconSection({icon, IconComponent, iconContainerStyles}) {
const styles = useThemeStyles();

return (
<View style={[styles.flexGrow1, styles.flexRow, styles.justifyContentEnd, ...iconContainerStyles]}>
{Boolean(icon) && (
<Icon
src={icon}
height={68}
width={68}
/>
)}
{Boolean(IconComponent) && <IconComponent />}
</View>
);
}

IconSection.displayName = 'IconSection';
IconSection.propTypes = iconSectionPropTypes;
IconSection.defaultProps = defaultIconSectionPropTypes;

export default IconSection;
57 changes: 38 additions & 19 deletions src/components/Section.js → src/components/Section/index.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
import PropTypes from 'prop-types';
import React from 'react';
import {View} from 'react-native';
import MenuItemList from '@components/MenuItemList';
import menuItemPropTypes from '@components/menuItemPropTypes';
import Text from '@components/Text';
import useThemeStyles from '@hooks/useThemeStyles';
import Icon from './Icon';
import MenuItemList from './MenuItemList';
import menuItemPropTypes from './menuItemPropTypes';
import Text from './Text';
import IconSection from './IconSection';

const CARD_LAYOUT = {
ICON_ON_TOP: 'iconOnTop',
ICON_ON_RIGHT: 'iconOnRight',
};

const propTypes = {
/** An array of props that are pass to individual MenuItem components */
Expand All @@ -23,6 +28,10 @@ const propTypes = {
/** Icon component */
IconComponent: PropTypes.func,

/** Card layout that affects icon positioning, margins, sizes. */
// eslint-disable-next-line rulesdir/prefer-underscore-method
cardLayout: PropTypes.oneOf(Object.values(CARD_LAYOUT)),

/** Contents to display inside the section */
children: PropTypes.node,

Expand All @@ -38,6 +47,9 @@ const propTypes = {
// eslint-disable-next-line react/forbid-prop-types
subtitleStyles: PropTypes.arrayOf(PropTypes.object),

/** Whether the subtitle should have a muted style */
subtitleMuted: PropTypes.bool,

/** Customize the Section container */
// eslint-disable-next-line react/forbid-prop-types
childrenStyles: PropTypes.arrayOf(PropTypes.object),
Expand All @@ -52,38 +64,45 @@ const defaultProps = {
children: null,
icon: null,
IconComponent: null,
cardLayout: CARD_LAYOUT.ICON_ON_RIGHT,
containerStyles: [],
iconContainerStyles: [],
titleStyles: [],
subtitleStyles: [],
subtitleMuted: false,
childrenStyles: [],
subtitle: null,
};

function Section({children, childrenStyles, containerStyles, icon, IconComponent, iconContainerStyles, menuItems, subtitle, subtitleStyles, title, titleStyles}) {
function Section({children, childrenStyles, containerStyles, icon, IconComponent, cardLayout, iconContainerStyles, menuItems, subtitle, subtitleStyles, subtitleMuted, title, titleStyles}) {
const styles = useThemeStyles();

return (
<>
<View style={[styles.pageWrapper, styles.cardSection, ...containerStyles]}>
<View style={[styles.flexRow, styles.alignItemsCenter, styles.w100, ...titleStyles]}>
{cardLayout === CARD_LAYOUT.ICON_ON_TOP && (
<IconSection
icon={icon}
IconComponent={IconComponent}
iconContainerStyles={[...iconContainerStyles, styles.alignSelfStart, styles.mb3]}
/>
)}
<View style={[styles.flexRow, styles.alignItemsCenter, styles.w100, cardLayout === CARD_LAYOUT.ICON_ON_TOP && styles.mh1, ...titleStyles]}>
<View style={[styles.flexShrink1]}>
<Text style={[styles.textHeadline, styles.cardSectionTitle]}>{title}</Text>
</View>
<View style={[styles.flexGrow1, styles.flexRow, styles.justifyContentEnd, ...iconContainerStyles]}>
{Boolean(icon) && (
<Icon
src={icon}
height={68}
width={68}
/>
)}
{Boolean(IconComponent) && <IconComponent />}
</View>
{cardLayout === CARD_LAYOUT.ICON_ON_RIGHT && (
<IconSection
icon={icon}
IconComponent={IconComponent}
iconContainerStyles={iconContainerStyles}
/>
)}
</View>

{Boolean(subtitle) && (
<View style={[styles.flexRow, styles.alignItemsCenter, styles.w100, styles.mt4, ...subtitleStyles]}>
<Text style={styles.textNormal}>{subtitle}</Text>
<View style={[styles.flexRow, styles.alignItemsCenter, styles.w100, cardLayout === CARD_LAYOUT.ICON_ON_TOP ? [styles.mt1, styles.mh1] : styles.mt4, ...subtitleStyles]}>
<Text style={[styles.textNormal, subtitleMuted && styles.colorMuted]}>{subtitle}</Text>
</View>
)}

Expand All @@ -94,9 +113,9 @@ function Section({children, childrenStyles, containerStyles, icon, IconComponent
</>
);
}

Section.displayName = 'Section';
Section.propTypes = propTypes;
Section.defaultProps = defaultProps;

export {CARD_LAYOUT};
export default Section;
5 changes: 3 additions & 2 deletions src/languages/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1489,8 +1489,9 @@ export default {
mustBeOnlineToViewMembers: 'You must be online in order to view members of this workspace.',
},
emptyWorkspace: {
title: 'Create a new workspace',
subtitle: "Workspaces are where you'll chat with your team, reimburse expenses, issue cards, send invoices, pay bills, and more — all in one place.",
title: 'Create a workspace',
subtitle: 'Manage business expenses, issue cards, send invoices, and more.',
createAWorkspaceCTA: 'Get Started',
features: {
trackAndCollect: 'Track and collect receipts',
companyCards: 'Company credit cards',
Expand Down
5 changes: 3 additions & 2 deletions src/languages/es.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1512,8 +1512,9 @@ export default {
mustBeOnlineToViewMembers: 'Debes estar en línea para poder ver los miembros de este espacio de trabajo.',
},
emptyWorkspace: {
title: 'Crear un nuevo espacio de trabajo',
subtitle: 'En los espacios de trabajo es donde puedes chatear con tu equipo, reembolsar gastos, emitir tarjetas, enviar y pagar facturas y mas — todo en un mismo lugar',
title: 'Crea un espacio de trabajo',
subtitle: 'Administra gastos de empresa, emite tarjetas, envía facturas y mucho más.',
createAWorkspaceCTA: 'Comenzar',
features: {
trackAndCollect: 'Organiza recibos',
companyCards: 'Tarjetas de crédito corporativas',
Expand Down
33 changes: 33 additions & 0 deletions src/pages/workspace/card/WorkspaceCardCreateAWorkspace.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import React from 'react';
import Button from '@components/Button';
import * as Illustrations from '@components/Icon/Illustrations';
import Section, {CARD_LAYOUT} from '@components/Section';
import useLocalize from '@hooks/useLocalize';
import useThemeStyles from '@hooks/useThemeStyles';

function WorkspaceCardCreateAWorkspace() {
const styles = useThemeStyles();
const {translate} = useLocalize();

return (
<Section
title={translate('workspace.emptyWorkspace.title')}
icon={Illustrations.HotDogStand}
cardLayout={CARD_LAYOUT.ICON_ON_TOP}
subtitle={translate('workspace.emptyWorkspace.subtitle')}
subtitleMuted
containerStyles={[styles.highlightBG]}
>
<Button
text={translate('workspace.emptyWorkspace.createAWorkspaceCTA')}
style={styles.mt5}
success
medium
/>
</Section>
);
}

WorkspaceCardCreateAWorkspace.displayName = 'WorkspaceCardNoVBAView';

export default WorkspaceCardCreateAWorkspace;
10 changes: 5 additions & 5 deletions src/styles/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -938,10 +938,14 @@ const styles = (theme: ThemeColors) =>
overflow: 'hidden',
},

calendarDayContainerSelected: {
buttonDefaultBG: {
backgroundColor: theme.buttonDefaultBG,
},

buttonHoveredBG: {
backgroundColor: theme.buttonHoveredBG,
},

autoGrowHeightInputContainer: (textInputHeight: number, minHeight: number, maxHeight: number) =>
({
height: lodashClamp(textInputHeight, minHeight, maxHeight),
Expand Down Expand Up @@ -1952,10 +1956,6 @@ const styles = (theme: ThemeColors) =>
alignSelf: 'flex-end',
},

hoveredButton: {
backgroundColor: theme.buttonHoveredBG,
},

composerSizeButton: {
alignSelf: 'center',
height: 32,
Expand Down

0 comments on commit 249096e

Please sign in to comment.