Merge branch 'feat/refresh' into feat/admin-ui-metrics

This commit is contained in:
Lucas Smith
2023-09-13 21:54:33 +10:00
committed by GitHub
19 changed files with 215 additions and 196 deletions

View File

@ -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`}
>
<AvatarFallback className={classes}>{fallbackText ?? 'UK'}</AvatarFallback>
<AvatarFallback className={classes}>{fallbackText}</AvatarFallback>
</Avatar>
);
};

View File

@ -1,5 +1,5 @@
import { initials } from '@documenso/lib/client-only/recipient-initials';
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={initials(recipient.name)}
fallbackText={recipientAbbreviation(recipient)}
/>
<span className="text-sm text-gray-500">{recipient.email}</span>
</div>
@ -73,7 +73,7 @@ export const StackAvatarsWithTooltip = ({
first={true}
key={recipient.id}
type={getRecipientType(recipient)}
fallbackText={initials(recipient.name)}
fallbackText={recipientAbbreviation(recipient)}
/>
<span className="text-sm text-gray-500">{recipient.email}</span>
</div>
@ -90,7 +90,7 @@ export const StackAvatarsWithTooltip = ({
first={true}
key={recipient.id}
type={getRecipientType(recipient)}
fallbackText={initials(recipient.name)}
fallbackText={recipientAbbreviation(recipient)}
/>
<span className="text-sm text-gray-500">{recipient.email}</span>
</div>
@ -107,7 +107,7 @@ export const StackAvatarsWithTooltip = ({
first={true}
key={recipient.id}
type={getRecipientType(recipient)}
fallbackText={initials(recipient.name)}
fallbackText={recipientAbbreviation(recipient)}
/>
<span className="text-sm text-gray-500">{recipient.email}</span>
</div>

View File

@ -1,7 +1,7 @@
import React from 'react';
import { initials } from '@documenso/lib/client-only/recipient-initials';
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 : initials(recipient.name)}
fallbackText={lastItemText ? lastItemText : recipientAbbreviation(recipient)}
/>
);
});

View File

@ -17,6 +17,7 @@ import { signOut } from 'next-auth/react';
import { useTheme } from 'next-themes';
import { isAdmin } from '@documenso/lib/next-auth/guards/is-admin';
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';
@ -42,19 +43,16 @@ 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
? recipientInitials(user.name)
: user.email.slice(0, 1).toUpperCase();
return (
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button variant="ghost" className="relative h-10 w-10 rounded-full">
<Avatar className="h-10 w-10">
<AvatarFallback>{initials}</AvatarFallback>
<AvatarFallback>{avatarFallback}</AvatarFallback>
</Avatar>
</Button>
</DropdownMenuTrigger>

View File

@ -2,16 +2,31 @@
import { HTMLAttributes, useEffect, useState } from 'react';
import { DateTime, DateTimeFormatOptions } from 'luxon';
import { useLocale } from '@documenso/lib/client-only/providers/locale';
export type LocaleDateProps = HTMLAttributes<HTMLSpanElement> & {
date: string | number | Date;
format?: DateTimeFormatOptions;
};
export const LocaleDate = ({ className, date, ...props }: LocaleDateProps) => {
const [localeDate, setLocaleDate] = useState(() => new Date(date).toISOString());
/**
* Formats the date based on the user locale.
*
* Will use the estimated locale from the user headers on SSR, then will use
* the client browser locale once mounted.
*/
export const LocaleDate = ({ className, date, format, ...props }: LocaleDateProps) => {
const { locale } = useLocale();
const [localeDate, setLocaleDate] = useState(() =>
DateTime.fromJSDate(new Date(date)).setLocale(locale).toLocaleString(format),
);
useEffect(() => {
setLocaleDate(new Date(date).toLocaleString());
}, [date]);
setLocaleDate(DateTime.fromJSDate(new Date(date)).toLocaleString(format));
}, [date, format]);
return (
<span className={className} {...props}>

View File

@ -18,13 +18,15 @@ import { Input } from '@documenso/ui/primitives/input';
import { Label } from '@documenso/ui/primitives/label';
import { useToast } from '@documenso/ui/primitives/use-toast';
const ErrorMessages = {
const ERROR_MESSAGES = {
[ErrorCode.CREDENTIALS_NOT_FOUND]: 'The email or password provided is incorrect',
[ErrorCode.INCORRECT_EMAIL_PASSWORD]: 'The email or password provided is incorrect',
[ErrorCode.USER_MISSING_PASSWORD]:
'This account appears to be using a social login method, please sign in using that method',
};
const LOGIN_REDIRECT_PATH = '/documents';
export const ZSignInFormSchema = z.object({
email: z.string().email().min(1),
password: z.string().min(6).max(72),
@ -37,9 +39,10 @@ export type SignInFormProps = {
};
export const SignInForm = ({ className }: SignInFormProps) => {
const { toast } = useToast();
const searchParams = useSearchParams();
const { toast } = useToast();
const {
register,
handleSubmit,
@ -61,7 +64,7 @@ export const SignInForm = ({ className }: SignInFormProps) => {
timeout = setTimeout(() => {
toast({
variant: 'destructive',
description: ErrorMessages[errorCode] ?? 'An unknown error occurred',
description: ERROR_MESSAGES[errorCode] ?? 'An unknown error occurred',
});
}, 0);
}
@ -78,12 +81,10 @@ export const SignInForm = ({ className }: SignInFormProps) => {
await signIn('credentials', {
email,
password,
callbackUrl: '/documents',
callbackUrl: LOGIN_REDIRECT_PATH,
}).catch((err) => {
console.error(err);
});
// throw new Error('Not implemented');
} catch (err) {
toast({
title: 'An unknown error occurred',
@ -95,8 +96,7 @@ export const SignInForm = ({ className }: SignInFormProps) => {
const onSignInWithGoogleClick = async () => {
try {
await signIn('google', { callbackUrl: '/dashboard' });
// throw new Error('Not implemented');
await signIn('google', { callbackUrl: LOGIN_REDIRECT_PATH });
} catch (err) {
toast({
title: 'An unknown error occurred',