Skip to content

Commit

Permalink
feat: extract SpaceSettings container component (#1053)
Browse files Browse the repository at this point in the history
  • Loading branch information
boris-w authored Nov 4, 2024
1 parent d1dbfb6 commit 15d74ef
Show file tree
Hide file tree
Showing 4 changed files with 99 additions and 79 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { useRouter } from 'next/router';
import { useTranslation } from 'next-i18next';
import { Collaborators } from '@/features/app/components/collaborator-manage/space/Collaborators';
import { SpaceCollaboratorModalTrigger } from '@/features/app/components/collaborator-manage/space/SpaceCollaboratorModalTrigger';
import { SpaceSettingContainer } from '@/features/app/components/SpaceSettingContainer';
import { spaceConfig } from '@/features/i18n/space.config';

export const CollaboratorPage = () => {
Expand All @@ -22,31 +23,25 @@ export const CollaboratorPage = () => {
});

return (
<div className="h-screen w-full overflow-y-auto overflow-x-hidden">
<div className="w-full px-8 py-6">
<div className="border-b pb-4">
<h1 className="text-3xl font-semibold">{t('space:spaceSetting.collaborators')}</h1>
<div className="mt-3 text-sm text-slate-500">
{t('space:spaceSetting.collaboratorDescription')}
</div>
<SpaceSettingContainer
title={t('space:spaceSetting.collaborators')}
description={t('space:spaceSetting.collaboratorDescription')}
>
{isHydrated && !!space && (
<div className="w-full py-4">
<Collaborators
spaceId={spaceId}
role={space.role}
collaboratorQuery={{ includeBase: true }}
>
<SpaceCollaboratorModalTrigger space={space}>
<Button size="sm">
<UserPlus className="size-4" /> {t('space:action.invite')}
</Button>
</SpaceCollaboratorModalTrigger>
</Collaborators>
</div>

{isHydrated && !!space && (
<div className="w-full py-4">
<Collaborators
spaceId={spaceId}
role={space.role}
collaboratorQuery={{ includeBase: true }}
>
<SpaceCollaboratorModalTrigger space={space}>
<Button size="sm">
<UserPlus className="size-4" /> {t('space:action.invite')}
</Button>
</SpaceCollaboratorModalTrigger>
</Collaborators>
</div>
)}
</div>
</div>
)}
</SpaceSettingContainer>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { useRouter } from 'next/router';
import { Trans, useTranslation } from 'next-i18next';
import { useState } from 'react';
import { CopyButton } from '@/features/app/components/CopyButton';
import { SpaceSettingContainer } from '@/features/app/components/SpaceSettingContainer';
import { spaceConfig } from '@/features/i18n/space.config';

export const GeneralPage = () => {
Expand Down Expand Up @@ -67,60 +68,57 @@ export const GeneralPage = () => {

return (
<>
<div className="h-screen w-full overflow-y-auto overflow-x-hidden">
<div className="w-full px-8 py-6">
<div className="border-b pb-4">
<h1 className="text-3xl font-semibold">{t('space:spaceSetting.general')}</h1>
{space && hasPermission(space.role, 'space|delete') && (
<div className="mt-3 text-sm text-slate-500">
{t('space:spaceSetting.generalDescription')}
</div>
)}
</div>

{!!space && (
<div className="flex flex-col gap-y-2 py-4">
<div className="flex justify-between">
<h2 className="mb-2 text-xl font-semibold">{t('common:noun.space')}</h2>
<Button variant="destructive" size="sm" onClick={() => setDeleteConfirm(true)}>
{t('actions.delete')}
</Button>
</div>
<div className="flex h-8 items-center gap-x-1 text-sm">
<span className="w-24 text-gray-500">{t('space:spaceSetting.spaceName')}</span>
{isEditing ? (
<Input
defaultValue={space.name}
onBlur={onBlur}
onKeyDown={onKeydown}
autoFocus
className="h-8"
/>
) : (
<>
<span>{space.name}</span>
{hasPermission(space.role, 'space|update') && (
<Button variant="ghost" size="xs" onClick={() => setIsEditing(true)}>
<Edit className="size-4 cursor-pointer text-gray-500" />
</Button>
)}
</>
)}
</div>
<div className="flex h-8 items-center gap-x-1 text-sm">
<span className="w-24 text-gray-500">{t('space:spaceSetting.spaceId')}</span>
<span>{spaceId}</span>
<CopyButton
variant="ghost"
text={spaceId}
size="xs"
iconClassName="size-4 text-gray-500"
<SpaceSettingContainer
title={t('space:spaceSetting.general')}
description={
space && hasPermission(space.role, 'space|delete')
? t('space:spaceSetting.generalDescription')
: undefined
}
>
{!!space && (
<div className="flex flex-col gap-y-2 py-4">
<div className="flex justify-between">
<h2 className="mb-2 text-xl font-semibold">{t('common:noun.space')}</h2>
<Button variant="destructive" size="sm" onClick={() => setDeleteConfirm(true)}>
{t('actions.delete')}
</Button>
</div>
<div className="flex h-8 items-center gap-x-1 text-sm">
<span className="w-24 text-gray-500">{t('space:spaceSetting.spaceName')}</span>
{isEditing ? (
<Input
defaultValue={space.name}
onBlur={onBlur}
onKeyDown={onKeydown}
autoFocus
className="h-8"
/>
</div>
) : (
<>
<span>{space.name}</span>
{hasPermission(space.role, 'space|update') && (
<Button variant="ghost" size="xs" onClick={() => setIsEditing(true)}>
<Edit className="size-4 cursor-pointer text-gray-500" />
</Button>
)}
</>
)}
</div>
)}
</div>
</div>
<div className="flex h-8 items-center gap-x-1 text-sm">
<span className="w-24 text-gray-500">{t('space:spaceSetting.spaceId')}</span>
<span>{spaceId}</span>
<CopyButton
variant="ghost"
text={spaceId}
size="xs"
iconClassName="size-4 text-gray-500"
/>
</div>
</div>
)}
</SpaceSettingContainer>

<ConfirmDialog
open={deleteConfirm}
onOpenChange={setDeleteConfirm}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
interface SpaceSettingContainerProps {
title: string;
description?: string;
className?: string;
children: React.ReactNode | React.ReactNode[];
}

export const SpaceSettingContainer = ({
title,
description,
className,
children,
}: SpaceSettingContainerProps) => {
return (
<div className="h-screen w-full overflow-y-auto overflow-x-hidden">
<div className="w-full px-8 py-6">
<div className="border-b pb-4">
<h1 className="text-3xl font-semibold">{title}</h1>
{description && <div className="mt-3 text-sm text-slate-500">{description}</div>}
</div>
<div className={className}>{children}</div>
</div>
</div>
);
};
6 changes: 4 additions & 2 deletions apps/nextjs-app/src/features/auth/pages/LoginPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,14 @@ import { Tabs, TabsList, TabsTrigger } from '@teable/ui-lib/shadcn';
import { useRouter } from 'next/router';
import { useTranslation } from 'next-i18next';
import { NextSeo } from 'next-seo';
import { useState, type FC, useCallback } from 'react';
import { useState, useCallback } from 'react';
import { authConfig } from '@/features/i18n/auth.config';
import type { ISignForm } from '../components/SignForm';
import { SignForm } from '../components/SignForm';
import { SocialAuth } from '../components/SocialAuth';

export const LoginPage: FC = () => {
export const LoginPage = (props: { children?: React.ReactNode | React.ReactNode[] }) => {
const { children } = props;
const { t } = useTranslation(authConfig.i18nNamespaces);
const router = useRouter();
const redirect = router.query.redirect as string;
Expand Down Expand Up @@ -37,6 +38,7 @@ export const LoginPage: FC = () => {
<div className="relative top-1/2 mx-auto w-80 -translate-y-1/2 py-[5em] lg:py-24">
<SignForm type={signType} onSuccess={onSuccess} />
<SocialAuth />
{children}
</div>
</div>
</>
Expand Down

0 comments on commit 15d74ef

Please sign in to comment.