Refactor function components across multiple files

Function components have been refactored across the codebase. Single export-const arrow function components have been adapted into traditional function declarations. This change provides better stack trace in case of errors and better function and argument names on runtime debugging.
This commit is contained in:
giancarlo
2024-05-05 13:31:40 +07:00
parent de15abb801
commit d7d3693f41
20 changed files with 144 additions and 88 deletions

View File

@@ -9,12 +9,7 @@ type Props = {
className?: string;
};
export const CoverImage: React.FC<Props> = ({
title,
src,
preloadImage,
className,
}) => {
export function CoverImage({ title, src, preloadImage, className }: Props) {
return (
<Image
className={cn(
@@ -30,4 +25,4 @@ export const CoverImage: React.FC<Props> = ({
fill
/>
);
};
}

View File

@@ -2,12 +2,10 @@ import { Cms } from '@kit/cms';
import { If } from '@kit/ui/if';
import { cn } from '@kit/ui/utils';
import { CoverImage } from '~/(marketing)/blog/_components/cover-image';
import { DateFormatter } from '~/(marketing)/blog/_components/date-formatter';
import { CoverImage } from './cover-image';
import { DateFormatter } from './date-formatter';
export const PostHeader: React.FC<{
post: Cms.ContentItem;
}> = ({ post }) => {
export function PostHeader({ post }: { post: Cms.ContentItem }) {
const { title, publishedAt, description, image } = post;
return (
@@ -45,4 +43,4 @@ export const PostHeader: React.FC<{
</If>
</div>
);
};
}

View File

@@ -4,10 +4,13 @@ import { ContentRenderer } from '@kit/cms';
import styles from './html-renderer.module.css';
import { PostHeader } from './post-header';
export const Post: React.FC<{
export function Post({
post,
content,
}: {
post: Cms.ContentItem;
content: unknown;
}> = ({ post, content }) => {
}) {
return (
<div>
<PostHeader post={post} />
@@ -19,4 +22,4 @@ export const Post: React.FC<{
</div>
</div>
);
};
}

View File

@@ -4,13 +4,16 @@ import { ChevronRight } from 'lucide-react';
import { Trans } from '@kit/ui/trans';
export const DocsCard: React.FC<
React.PropsWithChildren<{
title: string;
subtitle?: string | null;
link: { url: string; label?: string };
}>
> = ({ title, subtitle, children, link }) => {
export function DocsCard({
title,
subtitle,
children,
link,
}: React.PropsWithChildren<{
title: string;
subtitle?: string | null;
link: { url: string; label?: string };
}>) {
return (
<div className="flex flex-col">
<div
@@ -46,4 +49,4 @@ export const DocsCard: React.FC<
)}
</div>
);
};
}

View File

@@ -10,17 +10,20 @@ import { Menu } from 'lucide-react';
import { Cms } from '@kit/cms';
import { isBrowser } from '@kit/shared/utils';
import { Button } from '@kit/ui/button';
import { Heading } from '@kit/ui/heading';
import { If } from '@kit/ui/if';
import { Trans } from '@kit/ui/trans';
import { cn, isRouteActive } from '@kit/ui/utils';
const DocsNavLink: React.FC<{
function DocsNavLink({
label,
url,
level,
activePath,
}: {
label: string;
url: string;
level: number;
activePath: string;
}> = ({ label, url, level, activePath }) => {
}) {
const isCurrent = isRouteActive(url, activePath, 0);
const isFirstLevel = level === 0;
@@ -39,13 +42,17 @@ const DocsNavLink: React.FC<{
</Link>
</Button>
);
};
}
const Node: React.FC<{
function Node({
node,
level,
activePath,
}: {
node: Cms.ContentItem;
level: number;
activePath: string;
}> = ({ node, level, activePath }) => {
}) {
const pathPrefix = `/docs`;
const url = `${pathPrefix}/${node.url}`;
@@ -67,7 +74,7 @@ const Node: React.FC<{
)}
</>
);
};
}
function Tree({
pages,

View File

@@ -2,10 +2,13 @@ import Link from 'next/link';
import { cn } from '@kit/ui/utils';
const LogoImage: React.FC<{
function LogoImage({
className,
width = 105,
}: {
className?: string;
width?: number;
}> = ({ className, width = 105 }) => {
}) {
return (
<svg
width={width}
@@ -21,16 +24,20 @@ const LogoImage: React.FC<{
/>
</svg>
);
};
}
export const AppLogo: React.FC<{
export function AppLogo({
href,
label,
className,
}: {
href?: string;
className?: string;
label?: string;
}> = ({ href, label, className }) => {
}) {
return (
<Link aria-label={label ?? 'Home Page'} href={href ?? '/'}>
<LogoImage className={className} />
</Link>
);
};
}

View File

@@ -4,11 +4,15 @@ import { AtSign, Phone } from 'lucide-react';
const DEFAULT_IMAGE_SIZE = 18;
export const OauthProviderLogoImage: React.FC<{
export function OauthProviderLogoImage({
providerId,
width,
height,
}: {
providerId: string;
width?: number;
height?: number;
}> = ({ providerId, width, height }) => {
}) {
const image = getOAuthProviderLogos()[providerId];
if (typeof image === `string`) {
@@ -25,7 +29,7 @@ export const OauthProviderLogoImage: React.FC<{
}
return <>{image}</>;
};
}
function getOAuthProviderLogos(): Record<string, string | React.ReactNode> {
return {

View File

@@ -12,7 +12,7 @@ import { Trans } from '@kit/ui/trans';
import { AuthErrorAlert } from './auth-error-alert';
import { AuthProviderButton } from './auth-provider-button';
export const OauthProviders: React.FC<{
export function OauthProviders(props: {
inviteToken?: string;
enabledProviders: Provider[];
@@ -20,7 +20,7 @@ export const OauthProviders: React.FC<{
callback: string;
returnPath: string;
};
}> = (props) => {
}) {
const signInWithProviderMutation = useSignInWithProvider();
// we make the UI "busy" until the next page is fully loaded
@@ -102,7 +102,7 @@ export const OauthProviders: React.FC<{
</div>
</>
);
};
}
function getProviderName(providerId: string) {
const capitalize = (value: string) =>

View File

@@ -11,9 +11,11 @@ import type { PasswordSignInSchema } from '../schemas/password-sign-in.schema';
import { AuthErrorAlert } from './auth-error-alert';
import { PasswordSignInForm } from './password-sign-in-form';
export const PasswordSignInContainer: React.FC<{
export function PasswordSignInContainer({
onSignIn,
}: {
onSignIn?: (userId?: string) => unknown;
}> = ({ onSignIn }) => {
}) {
const { captchaToken, resetCaptchaToken } = useCaptchaToken();
const signInMutation = useSignInWithEmailPassword();
const isLoading = signInMutation.isPending;
@@ -47,4 +49,4 @@ export const PasswordSignInContainer: React.FC<{
<PasswordSignInForm onSubmit={onSubmit} loading={isLoading} />
</>
);
};
}

View File

@@ -23,10 +23,13 @@ import { Trans } from '@kit/ui/trans';
import { PasswordSignInSchema } from '../schemas/password-sign-in.schema';
export const PasswordSignInForm: React.FC<{
export function PasswordSignInForm({
onSubmit,
loading,
}: {
onSubmit: (params: z.infer<typeof PasswordSignInSchema>) => unknown;
loading: boolean;
}> = ({ onSubmit, loading }) => {
}) {
const { t } = useTranslation('auth');
const form = useForm<z.infer<typeof PasswordSignInSchema>>({
@@ -129,4 +132,4 @@ export const PasswordSignInForm: React.FC<{
</form>
</Form>
);
};
}

View File

@@ -21,14 +21,17 @@ import { Trans } from '@kit/ui/trans';
import { PasswordSignUpSchema } from '../schemas/password-sign-up.schema';
export const PasswordSignUpForm: React.FC<{
export function PasswordSignUpForm({
onSubmit,
loading,
}: {
onSubmit: (params: {
email: string;
password: string;
repeatPassword: string;
}) => unknown;
loading: boolean;
}> = ({ onSubmit, loading }) => {
}) {
const { t } = useTranslation();
const form = useForm({
@@ -148,4 +151,4 @@ export const PasswordSignUpForm: React.FC<{
</form>
</Form>
);
};
}

View File

@@ -16,11 +16,15 @@ import { Trans } from '@kit/ui/trans';
import { deleteInvitationAction } from '../../server/actions/team-invitations-server-actions';
export const DeleteInvitationDialog: React.FC<{
export function DeleteInvitationDialog({
isOpen,
setIsOpen,
invitationId,
}: {
isOpen: boolean;
setIsOpen: (isOpen: boolean) => void;
invitationId: number;
}> = ({ isOpen, setIsOpen, invitationId }) => {
}) {
return (
<AlertDialog open={isOpen} onOpenChange={setIsOpen}>
<AlertDialogContent>
@@ -41,7 +45,7 @@ export const DeleteInvitationDialog: React.FC<{
</AlertDialogContent>
</AlertDialog>
);
};
}
function DeleteInvitationForm({
invitationId,

View File

@@ -16,12 +16,17 @@ import { Trans } from '@kit/ui/trans';
import { renewInvitationAction } from '../../server/actions/team-invitations-server-actions';
export const RenewInvitationDialog: React.FC<{
export function RenewInvitationDialog({
isOpen,
setIsOpen,
invitationId,
email,
}: {
isOpen: boolean;
setIsOpen: (isOpen: boolean) => void;
invitationId: number;
email: string;
}> = ({ isOpen, setIsOpen, invitationId, email }) => {
}) {
return (
<AlertDialog open={isOpen} onOpenChange={setIsOpen}>
<AlertDialogContent>
@@ -45,7 +50,7 @@ export const RenewInvitationDialog: React.FC<{
</AlertDialogContent>
</AlertDialog>
);
};
}
function RenewInvitationForm({
invitationId,

View File

@@ -32,13 +32,19 @@ import { RolesDataProvider } from '../members/roles-data-provider';
type Role = string;
export const UpdateInvitationDialog: React.FC<{
export function UpdateInvitationDialog({
isOpen,
setIsOpen,
invitationId,
userRole,
userRoleHierarchy,
}: {
isOpen: boolean;
setIsOpen: (isOpen: boolean) => void;
invitationId: number;
userRole: Role;
userRoleHierarchy: number;
}> = ({ isOpen, setIsOpen, invitationId, userRole, userRoleHierarchy }) => {
}) {
return (
<Dialog open={isOpen} onOpenChange={setIsOpen}>
<DialogContent>
@@ -61,7 +67,7 @@ export const UpdateInvitationDialog: React.FC<{
</DialogContent>
</Dialog>
);
};
}
function UpdateInvitationForm({
invitationId,

View File

@@ -9,12 +9,17 @@ import { Trans } from '@kit/ui/trans';
type Role = string;
export const MembershipRoleSelector: React.FC<{
export function MembershipRoleSelector({
roles,
value,
currentUserRole,
onChange,
}: {
roles: Role[];
value: Role;
currentUserRole?: Role;
onChange: (role: Role) => unknown;
}> = ({ roles, value, currentUserRole, onChange }) => {
}) {
return (
<Select value={value} onValueChange={onChange}>
<SelectTrigger data-test={'role-selector-trigger'}>
@@ -39,4 +44,4 @@ export const MembershipRoleSelector: React.FC<{
</SelectContent>
</Select>
);
};
}

View File

@@ -16,12 +16,17 @@ import { Trans } from '@kit/ui/trans';
import { removeMemberFromAccountAction } from '../../server/actions/team-members-server-actions';
export const RemoveMemberDialog: React.FC<{
export function RemoveMemberDialog({
isOpen,
setIsOpen,
teamAccountId,
userId,
}: {
isOpen: boolean;
setIsOpen: (isOpen: boolean) => void;
teamAccountId: string;
userId: string;
}> = ({ isOpen, setIsOpen, teamAccountId, userId }) => {
}) {
return (
<AlertDialog open={isOpen} onOpenChange={setIsOpen}>
<AlertDialogContent>
@@ -43,7 +48,7 @@ export const RemoveMemberDialog: React.FC<{
</AlertDialogContent>
</AlertDialog>
);
};
}
function RemoveMemberForm({
accountId,

View File

@@ -17,9 +17,7 @@ const roleClassNameBuilder = cva('font-medium capitalize shadow-none', {
},
});
export const RoleBadge: React.FC<{
role: Role;
}> = ({ role }) => {
export function RoleBadge({ role }: { role: Role }) {
// @ts-expect-error: hard to type this since users can add custom roles
const className = roleClassNameBuilder({ role });
const isCustom = !(role in roles);
@@ -31,4 +29,4 @@ export const RoleBadge: React.FC<{
</span>
</Badge>
);
};
}

View File

@@ -32,13 +32,19 @@ import { Trans } from '@kit/ui/trans';
import { TransferOwnershipConfirmationSchema } from '../../schema/transfer-ownership-confirmation.schema';
import { transferOwnershipAction } from '../../server/actions/team-members-server-actions';
export const TransferOwnershipDialog: React.FC<{
export function TransferOwnershipDialog({
isOpen,
setIsOpen,
targetDisplayName,
accountId,
userId,
}: {
isOpen: boolean;
setIsOpen: (isOpen: boolean) => void;
accountId: string;
userId: string;
targetDisplayName: string;
}> = ({ isOpen, setIsOpen, targetDisplayName, accountId, userId }) => {
}) {
return (
<AlertDialog open={isOpen} onOpenChange={setIsOpen}>
<AlertDialogContent>
@@ -61,7 +67,7 @@ export const TransferOwnershipDialog: React.FC<{
</AlertDialogContent>
</AlertDialog>
);
};
}
function TransferOrganizationOwnershipForm({
accountId,

View File

@@ -32,21 +32,21 @@ import { RolesDataProvider } from './roles-data-provider';
type Role = string;
export const UpdateMemberRoleDialog: React.FC<{
isOpen: boolean;
setIsOpen: (isOpen: boolean) => void;
userId: string;
teamAccountId: string;
userRole: Role;
userRoleHierarchy: number;
}> = ({
export function UpdateMemberRoleDialog({
isOpen,
setIsOpen,
userId,
teamAccountId,
userRole,
userRoleHierarchy,
}) => {
}: {
isOpen: boolean;
setIsOpen: (isOpen: boolean) => void;
userId: string;
teamAccountId: string;
userRole: Role;
userRoleHierarchy: number;
}) {
return (
<Dialog open={isOpen} onOpenChange={setIsOpen}>
<DialogContent>
@@ -74,7 +74,7 @@ export const UpdateMemberRoleDialog: React.FC<{
</DialogContent>
</Dialog>
);
};
}
function UpdateMemberForm({
userId,

View File

@@ -15,12 +15,14 @@ import {
} from '../shadcn/dropdown-menu';
import { Trans } from './trans';
const MobileNavigationDropdown: React.FC<{
function MobileNavigationDropdown({
links,
}: {
links: {
path: string;
label: string;
}[];
}> = ({ links }) => {
}) {
const path = usePathname();
const items = useMemo(
@@ -70,6 +72,6 @@ const MobileNavigationDropdown: React.FC<{
<DropdownMenuContent>{items}</DropdownMenuContent>
</DropdownMenu>
);
};
}
export default MobileNavigationDropdown;