Added additional logic for handling website transfers.

This commit is contained in:
Mike Cao 2024-02-10 23:47:26 -08:00
parent 08b2f69658
commit a3f7382673
4 changed files with 43 additions and 45 deletions

View File

@ -1,53 +1,54 @@
import { Button, Modal, ModalTrigger, ActionForm, useToasts } from 'react-basics'; import { Button, Modal, ModalTrigger, ActionForm } from 'react-basics';
import { useRouter } from 'next/navigation'; import { useRouter } from 'next/navigation';
import { useMessages, useModified, useTeamUrl } from 'components/hooks'; import { useLogin, useMessages, useModified, useTeamUrl } from 'components/hooks';
import WebsiteDeleteForm from './WebsiteDeleteForm'; import WebsiteDeleteForm from './WebsiteDeleteForm';
import WebsiteResetForm from './WebsiteResetForm'; import WebsiteResetForm from './WebsiteResetForm';
import WebsiteTransferForm from './WebsiteTransferForm'; import WebsiteTransferForm from './WebsiteTransferForm';
import { ROLES } from 'lib/constants';
export function WebsiteData({ websiteId, onSave }: { websiteId: string; onSave?: () => void }) { export function WebsiteData({ websiteId, onSave }: { websiteId: string; onSave?: () => void }) {
const { formatMessage, labels, messages } = useMessages(); const { formatMessage, labels, messages } = useMessages();
const router = useRouter(); const { user } = useLogin();
const { showToast } = useToasts();
const { touch } = useModified(); const { touch } = useModified();
const { teamId, renderTeamUrl } = useTeamUrl(); const { teamId, renderTeamUrl } = useTeamUrl();
const router = useRouter();
const hasTeams = user?.teams?.length > 0;
const isTeamOwner =
(!teamId && hasTeams) ||
(hasTeams &&
user?.teams
?.find(({ id }) => id === teamId)
?.teamUser.find(({ role, userId }) => role === ROLES.teamOwner && userId === user.id));
const handleTransfer = () => { const handleSave = () => {
touch('websites'); touch('websites');
onSave?.();
router.push(renderTeamUrl(`/settings/websites`)); router.push(renderTeamUrl(`/settings/websites`));
}; };
const handleReset = async () => { const handleReset = async () => {
showToast({ message: formatMessage(messages.saved), variant: 'success' });
onSave?.(); onSave?.();
}; };
const handleDelete = async () => {
touch('websites');
if (teamId) {
router.push(renderTeamUrl('/settings/websites'));
} else {
router.push('/settings/websites');
}
};
return ( return (
<> <>
<ActionForm {process.env.cloudMode && (
label={formatMessage(labels.transferWebsite)} <ActionForm
description={formatMessage(messages.transferWebsite)} label={formatMessage(labels.transferWebsite)}
> description={formatMessage(messages.transferWebsite)}
<ModalTrigger> >
<Button variant="secondary">{formatMessage(labels.transfer)}</Button> <ModalTrigger disabled={!isTeamOwner}>
<Modal title={formatMessage(labels.transferWebsite)}> <Button variant="secondary" disabled={!isTeamOwner}>
{(close: () => void) => ( {formatMessage(labels.transfer)}
<WebsiteTransferForm websiteId={websiteId} onSave={handleTransfer} onClose={close} /> </Button>
)} <Modal title={formatMessage(labels.transferWebsite)}>
</Modal> {(close: () => void) => (
</ModalTrigger> <WebsiteTransferForm websiteId={websiteId} onSave={handleSave} onClose={close} />
</ActionForm> )}
</Modal>
</ModalTrigger>
</ActionForm>
)}
<ActionForm <ActionForm
label={formatMessage(labels.resetWebsite)} label={formatMessage(labels.resetWebsite)}
description={formatMessage(messages.resetWebsiteWarning)} description={formatMessage(messages.resetWebsiteWarning)}
@ -69,7 +70,7 @@ export function WebsiteData({ websiteId, onSave }: { websiteId: string; onSave?:
<Button variant="danger">{formatMessage(labels.delete)}</Button> <Button variant="danger">{formatMessage(labels.delete)}</Button>
<Modal title={formatMessage(labels.deleteWebsite)}> <Modal title={formatMessage(labels.deleteWebsite)}>
{(close: () => void) => ( {(close: () => void) => (
<WebsiteDeleteForm websiteId={websiteId} onSave={handleDelete} onClose={close} /> <WebsiteDeleteForm websiteId={websiteId} onSave={handleSave} onClose={close} />
)} )}
</Modal> </Modal>
</ModalTrigger> </ModalTrigger>

View File

@ -1,5 +1,5 @@
import { useState, Key, useContext } from 'react'; import { useState, Key, useContext } from 'react';
import { Item, Tabs, Button, Text, Icon } from 'react-basics'; import { Item, Tabs, Button, Text, Icon, useToasts } from 'react-basics';
import Link from 'next/link'; import Link from 'next/link';
import Icons from 'components/icons'; import Icons from 'components/icons';
import PageHeader from 'components/layout/PageHeader'; import PageHeader from 'components/layout/PageHeader';
@ -12,8 +12,13 @@ import { WebsiteContext } from 'app/(main)/websites/[websiteId]/WebsiteProvider'
export function WebsiteSettings({ websiteId, openExternal = false }) { export function WebsiteSettings({ websiteId, openExternal = false }) {
const website = useContext(WebsiteContext); const website = useContext(WebsiteContext);
const { formatMessage, labels } = useMessages(); const { formatMessage, labels, messages } = useMessages();
const [tab, setTab] = useState<Key>('details'); const [tab, setTab] = useState<Key>('details');
const { showToast } = useToasts();
const handleSave = () => {
showToast({ message: formatMessage(messages.saved), variant: 'success' });
};
return ( return (
<> <>
@ -36,7 +41,7 @@ export function WebsiteSettings({ websiteId, openExternal = false }) {
{tab === 'details' && <WebsiteEditForm websiteId={websiteId} />} {tab === 'details' && <WebsiteEditForm websiteId={websiteId} />}
{tab === 'tracking' && <TrackingCode websiteId={websiteId} />} {tab === 'tracking' && <TrackingCode websiteId={websiteId} />}
{tab === 'share' && <ShareUrl websiteId={websiteId} />} {tab === 'share' && <ShareUrl websiteId={websiteId} />}
{tab === 'data' && <WebsiteData websiteId={websiteId} />} {tab === 'data' && <WebsiteData websiteId={websiteId} onSave={handleSave} />}
</> </>
); );
} }

View File

@ -330,14 +330,14 @@ export const messages = defineMessages({
}, },
transferWebsite: { transferWebsite: {
id: 'message.transfer-website', id: 'message.transfer-website',
defaultMessage: 'Transfer website ownership to another user or team.', defaultMessage: 'Transfer website ownership to your account or another team.',
}, },
transferTeamWebsiteToUser: { transferTeamWebsiteToUser: {
id: 'message.transfer-team-website-to-user', id: 'message.transfer-team-website-to-user',
defaultMessage: 'Do you want to transfer this website to your account?', defaultMessage: 'Transfer this website to your account?',
}, },
transferUserWebsiteToTeam: { transferUserWebsiteToTeam: {
id: 'message.transfer-user-website-to-team', id: 'message.transfer-user-website-to-team',
defaultMessage: 'Which team do you want to transfer this website to?', defaultMessage: 'Select the team to transfer this website to.',
}, },
}); });

View File

@ -102,10 +102,6 @@ export async function canUpdateWebsite({ user }: Auth, websiteId: string) {
} }
export async function canTransferWebsiteToUser({ user }: Auth, websiteId: string, userId: string) { export async function canTransferWebsiteToUser({ user }: Auth, websiteId: string, userId: string) {
if (user.isAdmin) {
return true;
}
const website = await loadWebsite(websiteId); const website = await loadWebsite(websiteId);
if (website.teamId && user.id === userId) { if (website.teamId && user.id === userId) {
@ -118,10 +114,6 @@ export async function canTransferWebsiteToUser({ user }: Auth, websiteId: string
} }
export async function canTransferWebsiteToTeam({ user }: Auth, websiteId: string, teamId: string) { export async function canTransferWebsiteToTeam({ user }: Auth, websiteId: string, teamId: string) {
if (user.isAdmin) {
return true;
}
const website = await loadWebsite(websiteId); const website = await loadWebsite(websiteId);
if (website.userId === user.id) { if (website.userId === user.id) {