From fbf32404a6b859355e5a189d98756fc9da2a466f Mon Sep 17 00:00:00 2001 From: David Nguyen Date: Mon, 11 Sep 2023 16:58:41 +1000 Subject: [PATCH 1/2] feat: add avatar email fallback --- .../src/components/(dashboard)/avatar/stack-avatar.tsx | 4 ++-- .../(dashboard)/avatar/stack-avatars-with-tooltip.tsx | 10 +++++----- .../components/(dashboard)/avatar/stack-avatars.tsx | 4 ++-- .../components/(dashboard)/layout/profile-dropdown.tsx | 10 +++------- packages/lib/client-only/recipient-avatar-fallback.ts | 7 +++++++ packages/lib/client-only/recipient-initials.ts | 2 +- 6 files changed, 20 insertions(+), 17 deletions(-) create mode 100644 packages/lib/client-only/recipient-avatar-fallback.ts diff --git a/apps/web/src/components/(dashboard)/avatar/stack-avatar.tsx b/apps/web/src/components/(dashboard)/avatar/stack-avatar.tsx index 78814cd45..a2a81bb2a 100644 --- a/apps/web/src/components/(dashboard)/avatar/stack-avatar.tsx +++ b/apps/web/src/components/(dashboard)/avatar/stack-avatar.tsx @@ -15,7 +15,7 @@ export type StackAvatarProps = { type: 'unsigned' | 'waiting' | 'opened' | 'completed'; }; -export const StackAvatar = ({ first, zIndex, fallbackText, type }: StackAvatarProps) => { +export const StackAvatar = ({ first, zIndex, fallbackText = '', type }: StackAvatarProps) => { let classes = ''; let zIndexClass = ''; const firstClass = first ? '' : '-ml-3'; @@ -48,7 +48,7 @@ export const StackAvatar = ({ first, zIndex, fallbackText, type }: StackAvatarPr ${firstClass} dark:border-border h-10 w-10 border-2 border-solid border-white`} > - {fallbackText ?? 'UK'} + {fallbackText} ); }; diff --git a/apps/web/src/components/(dashboard)/avatar/stack-avatars-with-tooltip.tsx b/apps/web/src/components/(dashboard)/avatar/stack-avatars-with-tooltip.tsx index 2a053a35a..3f6407029 100644 --- a/apps/web/src/components/(dashboard)/avatar/stack-avatars-with-tooltip.tsx +++ b/apps/web/src/components/(dashboard)/avatar/stack-avatars-with-tooltip.tsx @@ -1,4 +1,4 @@ -import { initials } from '@documenso/lib/client-only/recipient-initials'; +import { recipientAvatarFallback } from '@documenso/lib/client-only/recipient-avatar-fallback'; import { getRecipientType } from '@documenso/lib/client-only/recipient-type'; import { Recipient } from '@documenso/prisma/client'; import { @@ -56,7 +56,7 @@ export const StackAvatarsWithTooltip = ({ first={true} key={recipient.id} type={getRecipientType(recipient)} - fallbackText={initials(recipient.name)} + fallbackText={recipientAvatarFallback(recipient)} /> {recipient.email} @@ -73,7 +73,7 @@ export const StackAvatarsWithTooltip = ({ first={true} key={recipient.id} type={getRecipientType(recipient)} - fallbackText={initials(recipient.name)} + fallbackText={recipientAvatarFallback(recipient)} /> {recipient.email} @@ -90,7 +90,7 @@ export const StackAvatarsWithTooltip = ({ first={true} key={recipient.id} type={getRecipientType(recipient)} - fallbackText={initials(recipient.name)} + fallbackText={recipientAvatarFallback(recipient)} /> {recipient.email} @@ -107,7 +107,7 @@ export const StackAvatarsWithTooltip = ({ first={true} key={recipient.id} type={getRecipientType(recipient)} - fallbackText={initials(recipient.name)} + fallbackText={recipientAvatarFallback(recipient)} /> {recipient.email} diff --git a/apps/web/src/components/(dashboard)/avatar/stack-avatars.tsx b/apps/web/src/components/(dashboard)/avatar/stack-avatars.tsx index 97af9dc9e..678836ffd 100644 --- a/apps/web/src/components/(dashboard)/avatar/stack-avatars.tsx +++ b/apps/web/src/components/(dashboard)/avatar/stack-avatars.tsx @@ -1,6 +1,6 @@ import React from 'react'; -import { initials } from '@documenso/lib/client-only/recipient-initials'; +import { recipientAvatarFallback } from '@documenso/lib/client-only/recipient-avatar-fallback'; import { getRecipientType } from '@documenso/lib/client-only/recipient-type'; import { Recipient } from '@documenso/prisma/client'; @@ -26,7 +26,7 @@ export function StackAvatars({ recipients }: { recipients: Recipient[] }) { first={first} zIndex={String(zIndex - index * 10)} type={lastItemText && index === 4 ? 'unsigned' : getRecipientType(recipient)} - fallbackText={lastItemText ? lastItemText : initials(recipient.name)} + fallbackText={lastItemText ? lastItemText : recipientAvatarFallback(recipient)} /> ); }); diff --git a/apps/web/src/components/(dashboard)/layout/profile-dropdown.tsx b/apps/web/src/components/(dashboard)/layout/profile-dropdown.tsx index 02af86d70..e52d9b42f 100644 --- a/apps/web/src/components/(dashboard)/layout/profile-dropdown.tsx +++ b/apps/web/src/components/(dashboard)/layout/profile-dropdown.tsx @@ -15,6 +15,7 @@ import { import { signOut } from 'next-auth/react'; import { useTheme } from 'next-themes'; +import { initials } from '@documenso/lib/client-only/recipient-initials'; import { User } from '@documenso/prisma/client'; import { Avatar, AvatarFallback } from '@documenso/ui/primitives/avatar'; import { Button } from '@documenso/ui/primitives/button'; @@ -40,19 +41,14 @@ export const ProfileDropdown = ({ user }: ProfileDropdownProps) => { const isBillingEnabled = getFlag('app_billing'); - const initials = - user.name - ?.split(' ') - .map((name: string) => name.slice(0, 1).toUpperCase()) - .slice(0, 2) - .join('') ?? 'UK'; + const avatarFallback = user.name ? initials(user.name) : user.email.slice(0, 1).toUpperCase(); return ( diff --git a/packages/lib/client-only/recipient-avatar-fallback.ts b/packages/lib/client-only/recipient-avatar-fallback.ts new file mode 100644 index 000000000..7a296a5fa --- /dev/null +++ b/packages/lib/client-only/recipient-avatar-fallback.ts @@ -0,0 +1,7 @@ +import { Recipient } from '@documenso/prisma/client'; + +import { initials } from './recipient-initials'; + +export const recipientAvatarFallback = (recipient: Recipient) => { + return initials(recipient.name) || recipient.email.slice(0, 1).toUpperCase(); +}; diff --git a/packages/lib/client-only/recipient-initials.ts b/packages/lib/client-only/recipient-initials.ts index 0712ccd7d..403ed26e4 100644 --- a/packages/lib/client-only/recipient-initials.ts +++ b/packages/lib/client-only/recipient-initials.ts @@ -3,4 +3,4 @@ export const initials = (text: string) => ?.split(' ') .map((name: string) => name.slice(0, 1).toUpperCase()) .slice(0, 2) - .join('') ?? 'UK'; + .join(''); From e8796a7d86cdf9be56da6fc8b88cb12360b506ab Mon Sep 17 00:00:00 2001 From: David Nguyen Date: Tue, 12 Sep 2023 12:33:04 +1000 Subject: [PATCH 2/2] refactor: organise recipient utils --- .../avatar/stack-avatars-with-tooltip.tsx | 10 +++++----- .../components/(dashboard)/avatar/stack-avatars.tsx | 4 ++-- .../(dashboard)/layout/profile-dropdown.tsx | 6 ++++-- .../lib/client-only/recipient-avatar-fallback.ts | 7 ------- packages/lib/client-only/recipient-initials.ts | 6 ------ packages/lib/utils/recipient-formatter.ts | 12 ++++++++++++ 6 files changed, 23 insertions(+), 22 deletions(-) delete mode 100644 packages/lib/client-only/recipient-avatar-fallback.ts delete mode 100644 packages/lib/client-only/recipient-initials.ts create mode 100644 packages/lib/utils/recipient-formatter.ts diff --git a/apps/web/src/components/(dashboard)/avatar/stack-avatars-with-tooltip.tsx b/apps/web/src/components/(dashboard)/avatar/stack-avatars-with-tooltip.tsx index 3f6407029..e36415813 100644 --- a/apps/web/src/components/(dashboard)/avatar/stack-avatars-with-tooltip.tsx +++ b/apps/web/src/components/(dashboard)/avatar/stack-avatars-with-tooltip.tsx @@ -1,5 +1,5 @@ -import { recipientAvatarFallback } from '@documenso/lib/client-only/recipient-avatar-fallback'; import { getRecipientType } from '@documenso/lib/client-only/recipient-type'; +import { recipientAbbreviation } from '@documenso/lib/utils/recipient-formatter'; import { Recipient } from '@documenso/prisma/client'; import { Tooltip, @@ -56,7 +56,7 @@ export const StackAvatarsWithTooltip = ({ first={true} key={recipient.id} type={getRecipientType(recipient)} - fallbackText={recipientAvatarFallback(recipient)} + fallbackText={recipientAbbreviation(recipient)} /> {recipient.email} @@ -73,7 +73,7 @@ export const StackAvatarsWithTooltip = ({ first={true} key={recipient.id} type={getRecipientType(recipient)} - fallbackText={recipientAvatarFallback(recipient)} + fallbackText={recipientAbbreviation(recipient)} /> {recipient.email} @@ -90,7 +90,7 @@ export const StackAvatarsWithTooltip = ({ first={true} key={recipient.id} type={getRecipientType(recipient)} - fallbackText={recipientAvatarFallback(recipient)} + fallbackText={recipientAbbreviation(recipient)} /> {recipient.email} @@ -107,7 +107,7 @@ export const StackAvatarsWithTooltip = ({ first={true} key={recipient.id} type={getRecipientType(recipient)} - fallbackText={recipientAvatarFallback(recipient)} + fallbackText={recipientAbbreviation(recipient)} /> {recipient.email} diff --git a/apps/web/src/components/(dashboard)/avatar/stack-avatars.tsx b/apps/web/src/components/(dashboard)/avatar/stack-avatars.tsx index 678836ffd..91f470f74 100644 --- a/apps/web/src/components/(dashboard)/avatar/stack-avatars.tsx +++ b/apps/web/src/components/(dashboard)/avatar/stack-avatars.tsx @@ -1,7 +1,7 @@ import React from 'react'; -import { recipientAvatarFallback } from '@documenso/lib/client-only/recipient-avatar-fallback'; import { getRecipientType } from '@documenso/lib/client-only/recipient-type'; +import { recipientAbbreviation } from '@documenso/lib/utils/recipient-formatter'; import { Recipient } from '@documenso/prisma/client'; import { StackAvatar } from './stack-avatar'; @@ -26,7 +26,7 @@ export function StackAvatars({ recipients }: { recipients: Recipient[] }) { first={first} zIndex={String(zIndex - index * 10)} type={lastItemText && index === 4 ? 'unsigned' : getRecipientType(recipient)} - fallbackText={lastItemText ? lastItemText : recipientAvatarFallback(recipient)} + fallbackText={lastItemText ? lastItemText : recipientAbbreviation(recipient)} /> ); }); diff --git a/apps/web/src/components/(dashboard)/layout/profile-dropdown.tsx b/apps/web/src/components/(dashboard)/layout/profile-dropdown.tsx index e52d9b42f..3b361e885 100644 --- a/apps/web/src/components/(dashboard)/layout/profile-dropdown.tsx +++ b/apps/web/src/components/(dashboard)/layout/profile-dropdown.tsx @@ -15,7 +15,7 @@ import { import { signOut } from 'next-auth/react'; import { useTheme } from 'next-themes'; -import { initials } from '@documenso/lib/client-only/recipient-initials'; +import { recipientInitials } from '@documenso/lib/utils/recipient-formatter'; import { User } from '@documenso/prisma/client'; import { Avatar, AvatarFallback } from '@documenso/ui/primitives/avatar'; import { Button } from '@documenso/ui/primitives/button'; @@ -41,7 +41,9 @@ export const ProfileDropdown = ({ user }: ProfileDropdownProps) => { const isBillingEnabled = getFlag('app_billing'); - const avatarFallback = user.name ? initials(user.name) : user.email.slice(0, 1).toUpperCase(); + const avatarFallback = user.name + ? recipientInitials(user.name) + : user.email.slice(0, 1).toUpperCase(); return ( diff --git a/packages/lib/client-only/recipient-avatar-fallback.ts b/packages/lib/client-only/recipient-avatar-fallback.ts deleted file mode 100644 index 7a296a5fa..000000000 --- a/packages/lib/client-only/recipient-avatar-fallback.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { Recipient } from '@documenso/prisma/client'; - -import { initials } from './recipient-initials'; - -export const recipientAvatarFallback = (recipient: Recipient) => { - return initials(recipient.name) || recipient.email.slice(0, 1).toUpperCase(); -}; diff --git a/packages/lib/client-only/recipient-initials.ts b/packages/lib/client-only/recipient-initials.ts deleted file mode 100644 index 403ed26e4..000000000 --- a/packages/lib/client-only/recipient-initials.ts +++ /dev/null @@ -1,6 +0,0 @@ -export const initials = (text: string) => - text - ?.split(' ') - .map((name: string) => name.slice(0, 1).toUpperCase()) - .slice(0, 2) - .join(''); diff --git a/packages/lib/utils/recipient-formatter.ts b/packages/lib/utils/recipient-formatter.ts new file mode 100644 index 000000000..da404830b --- /dev/null +++ b/packages/lib/utils/recipient-formatter.ts @@ -0,0 +1,12 @@ +import { Recipient } from '@documenso/prisma/client'; + +export const recipientInitials = (text: string) => + text + .split(' ') + .map((name: string) => name.slice(0, 1).toUpperCase()) + .slice(0, 2) + .join(''); + +export const recipientAbbreviation = (recipient: Recipient) => { + return recipientInitials(recipient.name) || recipient.email.slice(0, 1).toUpperCase(); +};