From 33c4d992e90c86eec74f82318205a3a855e47ccf Mon Sep 17 00:00:00 2001 From: strzelec Date: Tue, 22 Oct 2024 12:13:02 +0200 Subject: [PATCH 1/3] feat: create colony cards for landing page --- .../frame/LandingPage/ColonyCard.tsx | 107 ++++++++++++++++++ src/i18n/en.json | 3 + src/stories/common/ColonyCard.stories.tsx | 72 ++++++++++++ tailwind.config.js | 1 + 4 files changed, 183 insertions(+) create mode 100644 src/components/frame/LandingPage/ColonyCard.tsx create mode 100644 src/stories/common/ColonyCard.stories.tsx diff --git a/src/components/frame/LandingPage/ColonyCard.tsx b/src/components/frame/LandingPage/ColonyCard.tsx new file mode 100644 index 0000000000..c790d3ad35 --- /dev/null +++ b/src/components/frame/LandingPage/ColonyCard.tsx @@ -0,0 +1,107 @@ +import { Plus } from '@phosphor-icons/react'; +import clsx from 'clsx'; +import React from 'react'; + +import LoadingSkeleton from '~common/LoadingSkeleton/LoadingSkeleton.tsx'; +import { formatText } from '~utils/intl.ts'; +import Button from '~v5/shared/Button/Button.tsx'; + +export interface ColonyCardProps { + colonyName?: string; + colonyAvatar?: string; + membersCount?: number; + invitationsRemaining?: number; + loading?: boolean; + onCreate?: () => void; +} + +const displayName = 'frame.LandingPage'; + +export const ColonyCard = ({ + colonyName, + colonyAvatar, + invitationsRemaining, + membersCount = 0, + loading, + onCreate, +}: ColonyCardProps) => { + return ( +
+
+ + {colonyName && colonyAvatar ? ( + Colony avatar + ) : ( +
+ +
+ )} +
+
+ {loading ? ( +
+ + +
+ ) : ( +
+ {colonyName ? ( +

{colonyName}

+ ) : ( +
+
+ + {formatText( + { + id: 'landingPage.card.remaining', + }, + { remaining: invitationsRemaining }, + ).toUpperCase()} + +
+

+ {formatText({ + id: 'landingPage.card.createColony', + })} +

+
+ )} + + {colonyName ? ( +

+ {formatText( + { + id: 'landingPage.card.members', + }, + { members: membersCount.toLocaleString('en-US') }, + )} +

+ ) : ( + + )} +
+ )} +
+ ); +}; + +ColonyCard.displayName = displayName; + +export default ColonyCard; diff --git a/src/i18n/en.json b/src/i18n/en.json index e45b9fe439..8065840ac3 100644 --- a/src/i18n/en.json +++ b/src/i18n/en.json @@ -54,6 +54,9 @@ "home": "Home", "wallet": "Wallet", "colonyWelcome": "Welcome to Colony", + "landingPage.card.members": "{members} Members", + "landingPage.card.createColony": "Create a new colony", + "landingPage.card.remaining": "{remaining} invitations remaining", "domain.all": "All Teams", "domain.root": "Root", "role.disabled": "Disabled", diff --git a/src/stories/common/ColonyCard.stories.tsx b/src/stories/common/ColonyCard.stories.tsx new file mode 100644 index 0000000000..2a270c84b2 --- /dev/null +++ b/src/stories/common/ColonyCard.stories.tsx @@ -0,0 +1,72 @@ +import { type Meta, type StoryObj } from '@storybook/react'; +import React from 'react'; + +import ColonyCard from '~frame/LandingPage/ColonyCard.tsx'; + +const meta: Meta = { + title: 'Common/Colony Card', + component: ColonyCard, + decorators: [ + (Story) => ( +
+ +
+ ), + ], + argTypes: { + colonyName: { + name: 'Colony name', + control: { + type: 'text', + }, + }, + colonyAvatar: { + name: 'Colony avatar', + control: { + type: 'text', + }, + }, + membersCount: { + name: 'Members count', + control: { + type: 'number', + }, + }, + invitationsRemaining: { + name: 'Invitations remaining', + control: { + type: 'number', + }, + }, + loading: { + name: 'Loading', + control: { + type: 'boolean', + }, + }, + }, +}; + +export default meta; +type Story = StoryObj; + +export const ActiveColony: Story = { + args: { + colonyName: 'Beta colony', + colonyAvatar: 'https://picsum.photos/200', + membersCount: 1520, + invitationsRemaining: 2, + }, +}; + +export const CreateColony: Story = { + args: { + invitationsRemaining: 3, + }, +}; + +export const Loading: Story = { + args: { + loading: true, + }, +}; diff --git a/tailwind.config.js b/tailwind.config.js index 4692d86b24..3f799d9a04 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -112,6 +112,7 @@ module.exports = { inter: ['Inter', 'sans-serif'], }, fontSize: { + '2xs': ['.5rem', 1.5], xs: ['0.625rem', 1.6], sm: ['0.75rem', 1.5], md: ['0.875rem', '1.25rem'], From e0c9a6da272705dbf5033b7a1313a2dc1154d17d Mon Sep 17 00:00:00 2001 From: strzelec Date: Wed, 23 Oct 2024 14:15:12 +0200 Subject: [PATCH 2/3] fix: refactor colony cards --- .../frame/LandingPage/ColonyCard.tsx | 107 ------------------ .../BaseColonyCard/BaseColonyCard.tsx | 32 ++++++ .../LandingPage/ColonyCards/ColonyCard.tsx | 44 +++++++ .../ColonyCards/ColonyCardSkeleton.tsx | 24 ++++ .../ColonyCards/CreateNewColonyCard.tsx | 54 +++++++++ src/i18n/en.json | 1 + src/stories/common/ColonyCard.stories.tsx | 29 +---- .../common/ColonyCardSkeleton.stories.tsx | 25 ++++ .../common/CreateNewColonyCard.stories.tsx | 33 ++++++ 9 files changed, 215 insertions(+), 134 deletions(-) delete mode 100644 src/components/frame/LandingPage/ColonyCard.tsx create mode 100644 src/components/frame/LandingPage/ColonyCards/BaseColonyCard/BaseColonyCard.tsx create mode 100644 src/components/frame/LandingPage/ColonyCards/ColonyCard.tsx create mode 100644 src/components/frame/LandingPage/ColonyCards/ColonyCardSkeleton.tsx create mode 100644 src/components/frame/LandingPage/ColonyCards/CreateNewColonyCard.tsx create mode 100644 src/stories/common/ColonyCardSkeleton.stories.tsx create mode 100644 src/stories/common/CreateNewColonyCard.stories.tsx diff --git a/src/components/frame/LandingPage/ColonyCard.tsx b/src/components/frame/LandingPage/ColonyCard.tsx deleted file mode 100644 index c790d3ad35..0000000000 --- a/src/components/frame/LandingPage/ColonyCard.tsx +++ /dev/null @@ -1,107 +0,0 @@ -import { Plus } from '@phosphor-icons/react'; -import clsx from 'clsx'; -import React from 'react'; - -import LoadingSkeleton from '~common/LoadingSkeleton/LoadingSkeleton.tsx'; -import { formatText } from '~utils/intl.ts'; -import Button from '~v5/shared/Button/Button.tsx'; - -export interface ColonyCardProps { - colonyName?: string; - colonyAvatar?: string; - membersCount?: number; - invitationsRemaining?: number; - loading?: boolean; - onCreate?: () => void; -} - -const displayName = 'frame.LandingPage'; - -export const ColonyCard = ({ - colonyName, - colonyAvatar, - invitationsRemaining, - membersCount = 0, - loading, - onCreate, -}: ColonyCardProps) => { - return ( -
-
- - {colonyName && colonyAvatar ? ( - Colony avatar - ) : ( -
- -
- )} -
-
- {loading ? ( -
- - -
- ) : ( -
- {colonyName ? ( -

{colonyName}

- ) : ( -
-
- - {formatText( - { - id: 'landingPage.card.remaining', - }, - { remaining: invitationsRemaining }, - ).toUpperCase()} - -
-

- {formatText({ - id: 'landingPage.card.createColony', - })} -

-
- )} - - {colonyName ? ( -

- {formatText( - { - id: 'landingPage.card.members', - }, - { members: membersCount.toLocaleString('en-US') }, - )} -

- ) : ( - - )} -
- )} -
- ); -}; - -ColonyCard.displayName = displayName; - -export default ColonyCard; diff --git a/src/components/frame/LandingPage/ColonyCards/BaseColonyCard/BaseColonyCard.tsx b/src/components/frame/LandingPage/ColonyCards/BaseColonyCard/BaseColonyCard.tsx new file mode 100644 index 0000000000..21a0559ef0 --- /dev/null +++ b/src/components/frame/LandingPage/ColonyCards/BaseColonyCard/BaseColonyCard.tsx @@ -0,0 +1,32 @@ +import clsx from 'clsx'; +import React, { type PropsWithChildren } from 'react'; + +const displayName = 'frame.LandingPage.ColonyCards.BaseColonyCard'; + +export interface BaseColonyCardProps extends PropsWithChildren { + avatarPlaceholder: React.ReactNode; + isClickable?: boolean; +} +const BaseColonyCard = ({ + isClickable, + avatarPlaceholder, + children, +}: BaseColonyCardProps) => ( +
+
+ {avatarPlaceholder} +
+
{children}
+
+); + +BaseColonyCard.displayName = displayName; + +export default BaseColonyCard; diff --git a/src/components/frame/LandingPage/ColonyCards/ColonyCard.tsx b/src/components/frame/LandingPage/ColonyCards/ColonyCard.tsx new file mode 100644 index 0000000000..f351281dbc --- /dev/null +++ b/src/components/frame/LandingPage/ColonyCards/ColonyCard.tsx @@ -0,0 +1,44 @@ +import React from 'react'; + +import { formatText } from '~utils/intl.ts'; + +import BaseColonyCard from './BaseColonyCard/BaseColonyCard.tsx'; + +export interface ColonyCardProps { + colonyName: string; + colonyAvatar: string; + membersCount: number; +} + +const displayName = 'frame.LandingPage.ColonyCards'; + +export const ColonyCard = ({ + colonyName, + colonyAvatar, + membersCount = 0, +}: ColonyCardProps) => ( + + } + > +

{colonyName}

+

+ {formatText( + { + id: 'landingPage.card.members', + }, + { members: membersCount.toLocaleString('en-US') }, + )} +

+
+); + +ColonyCard.displayName = displayName; + +export default ColonyCard; diff --git a/src/components/frame/LandingPage/ColonyCards/ColonyCardSkeleton.tsx b/src/components/frame/LandingPage/ColonyCards/ColonyCardSkeleton.tsx new file mode 100644 index 0000000000..daecef0f4e --- /dev/null +++ b/src/components/frame/LandingPage/ColonyCards/ColonyCardSkeleton.tsx @@ -0,0 +1,24 @@ +import React from 'react'; + +import LoadingSkeleton from '~common/LoadingSkeleton/LoadingSkeleton.tsx'; + +import BaseColonyCard from './BaseColonyCard/BaseColonyCard.tsx'; + +const displayName = 'frame.LandingPage.ColonyCards'; + +export const ColonyCardSkeleton = () => ( + + } + > +
+ + +
+
+); + +ColonyCardSkeleton.displayName = displayName; + +export default ColonyCardSkeleton; diff --git a/src/components/frame/LandingPage/ColonyCards/CreateNewColonyCard.tsx b/src/components/frame/LandingPage/ColonyCards/CreateNewColonyCard.tsx new file mode 100644 index 0000000000..4f3c7f87bf --- /dev/null +++ b/src/components/frame/LandingPage/ColonyCards/CreateNewColonyCard.tsx @@ -0,0 +1,54 @@ +import { Plus } from '@phosphor-icons/react'; +import React from 'react'; + +import { formatText } from '~utils/intl.ts'; +import Button from '~v5/shared/Button/Button.tsx'; + +import BaseColonyCard from './BaseColonyCard/BaseColonyCard.tsx'; + +const displayName = 'frame.LandingPage.ColonyCards'; + +export interface ColonyCreateCardProps { + invitationsRemaining: number; + onCreate: () => void; +} +export const CreateNewColonyCard = ({ + invitationsRemaining, + onCreate, +}: ColonyCreateCardProps) => ( + + + + } + > +
+
+ + {formatText( + { + id: 'landingPage.card.remaining', + }, + { remaining: invitationsRemaining }, + ).toUpperCase()} + +
+

+ {formatText({ + id: 'landingPage.card.createColony', + })} +

+
+ +
+); + +CreateNewColonyCard.displayName = displayName; + +export default CreateNewColonyCard; diff --git a/src/i18n/en.json b/src/i18n/en.json index 8065840ac3..e31d504807 100644 --- a/src/i18n/en.json +++ b/src/i18n/en.json @@ -57,6 +57,7 @@ "landingPage.card.members": "{members} Members", "landingPage.card.createColony": "Create a new colony", "landingPage.card.remaining": "{remaining} invitations remaining", + "landingPage.card.createButton": "Create", "domain.all": "All Teams", "domain.root": "Root", "role.disabled": "Disabled", diff --git a/src/stories/common/ColonyCard.stories.tsx b/src/stories/common/ColonyCard.stories.tsx index 2a270c84b2..21699ce264 100644 --- a/src/stories/common/ColonyCard.stories.tsx +++ b/src/stories/common/ColonyCard.stories.tsx @@ -1,7 +1,7 @@ import { type Meta, type StoryObj } from '@storybook/react'; import React from 'react'; -import ColonyCard from '~frame/LandingPage/ColonyCard.tsx'; +import ColonyCard from '~frame/LandingPage/ColonyCards/ColonyCard.tsx'; const meta: Meta = { title: 'Common/Colony Card', @@ -32,41 +32,16 @@ const meta: Meta = { type: 'number', }, }, - invitationsRemaining: { - name: 'Invitations remaining', - control: { - type: 'number', - }, - }, - loading: { - name: 'Loading', - control: { - type: 'boolean', - }, - }, }, }; export default meta; type Story = StoryObj; -export const ActiveColony: Story = { +export const Base: Story = { args: { colonyName: 'Beta colony', colonyAvatar: 'https://picsum.photos/200', membersCount: 1520, - invitationsRemaining: 2, - }, -}; - -export const CreateColony: Story = { - args: { - invitationsRemaining: 3, - }, -}; - -export const Loading: Story = { - args: { - loading: true, }, }; diff --git a/src/stories/common/ColonyCardSkeleton.stories.tsx b/src/stories/common/ColonyCardSkeleton.stories.tsx new file mode 100644 index 0000000000..b40b84b704 --- /dev/null +++ b/src/stories/common/ColonyCardSkeleton.stories.tsx @@ -0,0 +1,25 @@ +import { type Meta, type StoryObj } from '@storybook/react'; +import React from 'react'; + +import ColonyCardSkeleton from '~frame/LandingPage/ColonyCards/ColonyCardSkeleton.tsx'; + +const meta: Meta = { + title: 'Common/Colony Card Skeleton', + component: ColonyCardSkeleton, + decorators: [ + (Story) => ( +
+ +
+ ), + ], +}; + +export default meta; +type Story = StoryObj; + +export const Base: Story = { + args: { + invitationsRemaining: 2, + }, +}; diff --git a/src/stories/common/CreateNewColonyCard.stories.tsx b/src/stories/common/CreateNewColonyCard.stories.tsx new file mode 100644 index 0000000000..3a12318f3f --- /dev/null +++ b/src/stories/common/CreateNewColonyCard.stories.tsx @@ -0,0 +1,33 @@ +import { type Meta, type StoryObj } from '@storybook/react'; +import React from 'react'; + +import CreateNewColonyCard from '~frame/LandingPage/ColonyCards/CreateNewColonyCard.tsx'; + +const meta: Meta = { + title: 'Common/Create New Colony Card', + component: CreateNewColonyCard, + decorators: [ + (Story) => ( +
+ +
+ ), + ], + argTypes: { + invitationsRemaining: { + name: 'Invitation remaining', + control: { + type: 'number', + }, + }, + }, +}; + +export default meta; +type Story = StoryObj; + +export const Base: Story = { + args: { + invitationsRemaining: 2, + }, +}; From 60fbdf6d2d2bcc399a67da8a1f2ea0192eadfe37 Mon Sep 17 00:00:00 2001 From: strzelec Date: Wed, 23 Oct 2024 15:09:06 +0200 Subject: [PATCH 3/3] fix: define messages inside components --- .../LandingPage/ColonyCards/ColonyCard.tsx | 20 ++++++----- .../ColonyCards/CreateNewColonyCard.tsx | 36 ++++++++++++------- src/i18n/en.json | 4 --- 3 files changed, 35 insertions(+), 25 deletions(-) diff --git a/src/components/frame/LandingPage/ColonyCards/ColonyCard.tsx b/src/components/frame/LandingPage/ColonyCards/ColonyCard.tsx index f351281dbc..2d87bf59c0 100644 --- a/src/components/frame/LandingPage/ColonyCards/ColonyCard.tsx +++ b/src/components/frame/LandingPage/ColonyCards/ColonyCard.tsx @@ -1,6 +1,5 @@ import React from 'react'; - -import { formatText } from '~utils/intl.ts'; +import { defineMessages, FormattedMessage } from 'react-intl'; import BaseColonyCard from './BaseColonyCard/BaseColonyCard.tsx'; @@ -12,6 +11,13 @@ export interface ColonyCardProps { const displayName = 'frame.LandingPage.ColonyCards'; +const MSG = defineMessages({ + members: { + id: `${displayName}.members`, + defaultMessage: `{members} Members`, + }, +}); + export const ColonyCard = ({ colonyName, colonyAvatar, @@ -29,12 +35,10 @@ export const ColonyCard = ({ >

{colonyName}

- {formatText( - { - id: 'landingPage.card.members', - }, - { members: membersCount.toLocaleString('en-US') }, - )} +

); diff --git a/src/components/frame/LandingPage/ColonyCards/CreateNewColonyCard.tsx b/src/components/frame/LandingPage/ColonyCards/CreateNewColonyCard.tsx index 4f3c7f87bf..72e5837913 100644 --- a/src/components/frame/LandingPage/ColonyCards/CreateNewColonyCard.tsx +++ b/src/components/frame/LandingPage/ColonyCards/CreateNewColonyCard.tsx @@ -1,7 +1,7 @@ import { Plus } from '@phosphor-icons/react'; import React from 'react'; +import { defineMessages, FormattedMessage } from 'react-intl'; -import { formatText } from '~utils/intl.ts'; import Button from '~v5/shared/Button/Button.tsx'; import BaseColonyCard from './BaseColonyCard/BaseColonyCard.tsx'; @@ -12,6 +12,22 @@ export interface ColonyCreateCardProps { invitationsRemaining: number; onCreate: () => void; } + +const MSG = defineMessages({ + remaining: { + id: `${displayName}.remaining`, + defaultMessage: `{remaining} INVITATIONS REMANING`, + }, + createColony: { + id: `${displayName}.createColony`, + defaultMessage: `Create a new colony`, + }, + createButton: { + id: `${displayName}.createButton`, + defaultMessage: `Create`, + }, +}); + export const CreateNewColonyCard = ({ invitationsRemaining, onCreate, @@ -27,24 +43,18 @@ export const CreateNewColonyCard = ({
- {formatText( - { - id: 'landingPage.card.remaining', - }, - { remaining: invitationsRemaining }, - ).toUpperCase()} +

- {formatText({ - id: 'landingPage.card.createColony', - })} +

); diff --git a/src/i18n/en.json b/src/i18n/en.json index e31d504807..e45b9fe439 100644 --- a/src/i18n/en.json +++ b/src/i18n/en.json @@ -54,10 +54,6 @@ "home": "Home", "wallet": "Wallet", "colonyWelcome": "Welcome to Colony", - "landingPage.card.members": "{members} Members", - "landingPage.card.createColony": "Create a new colony", - "landingPage.card.remaining": "{remaining} invitations remaining", - "landingPage.card.createButton": "Create", "domain.all": "All Teams", "domain.root": "Root", "role.disabled": "Disabled",