diff --git a/apps/studio/components/interfaces/Auth/EmailTemplates/CustomEmailTemplateRestrictionAdmonition.tsx b/apps/studio/components/interfaces/Auth/EmailTemplates/CustomEmailTemplateRestrictionAdmonition.tsx index 93603c72b21..7454dba049b 100644 --- a/apps/studio/components/interfaces/Auth/EmailTemplates/CustomEmailTemplateRestrictionAdmonition.tsx +++ b/apps/studio/components/interfaces/Auth/EmailTemplates/CustomEmailTemplateRestrictionAdmonition.tsx @@ -1,8 +1,15 @@ +import { ChevronDown } from 'lucide-react' import Link from 'next/link' -import { Button } from 'ui' +import { + Button, + DropdownMenu, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuTrigger, +} from 'ui' import { Admonition } from 'ui-patterns/admonition' -import { UpgradePlanButton } from '@/components/ui/UpgradePlanButton' +import { useSelectedOrganizationQuery } from '@/hooks/misc/useSelectedOrganization' interface CustomEmailTemplateRestrictionAdmonitionProps { projectRef?: string @@ -11,27 +18,41 @@ interface CustomEmailTemplateRestrictionAdmonitionProps { export const CustomEmailTemplateRestrictionAdmonition = ({ projectRef, }: CustomEmailTemplateRestrictionAdmonitionProps) => { + const { data: selectedOrganization } = useSelectedOrganizationQuery() + const organizationSlug = selectedOrganization?.slug ?? '_' + return ( - - - - Upgrade to Pro - + + + + + + + + Upgrade to Pro + + + + + Configure send-email hook + + + + } /> diff --git a/apps/studio/components/interfaces/Auth/EmailTemplates/TemplateEditor.tsx b/apps/studio/components/interfaces/Auth/EmailTemplates/TemplateEditor.tsx index d7d6da4484b..50eb14e61a3 100644 --- a/apps/studio/components/interfaces/Auth/EmailTemplates/TemplateEditor.tsx +++ b/apps/studio/components/interfaces/Auth/EmailTemplates/TemplateEditor.tsx @@ -24,6 +24,7 @@ import { FormItemLayout } from 'ui-patterns/form/FormItemLayout/FormItemLayout' import { SpamValidation } from './SpamValidation' import { PreventNavigationOnUnsavedChanges } from '@/components/ui-patterns/Dialogs/PreventNavigationOnUnsavedChanges' +import { ButtonTooltip } from '@/components/ui/ButtonTooltip' import CodeEditor from '@/components/ui/CodeEditor/CodeEditor' import { TwoOptionToggle } from '@/components/ui/TwoOptionToggle' import { useAuthConfigQuery } from '@/data/auth/auth-config-query' @@ -169,6 +170,11 @@ export const TemplateEditor = ({ template, isReadOnly = false }: TemplateEditorP const baselineBodyValue = (authConfig && authConfig[messageSlug]) ?? '' const hasFormChanges = JSON.stringify(formValues) !== JSON.stringify(baselineValues) const hasChanges = hasFormChanges || baselineBodyValue !== bodyValue + const saveChangesTooltip = !canEdit + ? 'Set up Custom SMTP to edit and save templates' + : !hasChanges + ? 'Make a change before saving' + : undefined // Function to insert text at cursor position const insertTextAtCursor = (text: string) => { @@ -229,6 +235,10 @@ export const TemplateEditor = ({ template, isReadOnly = false }: TemplateEditorP if (!hasChanges) setValidationResult(undefined) }, [hasChanges]) + useEffect(() => { + if (!canEdit) setActiveView('preview') + }, [canEdit]) + return (
@@ -282,8 +292,13 @@ export const TemplateEditor = ({ template, isReadOnly = false }: TemplateEditorP width={60} options={['preview', 'source']} activeOption={activeView} - onClickOption={(option) => setActiveView(option as 'source' | 'preview')} + onClickOption={(option) => { + if (!canEdit && option === 'source') return + setActiveView(option as 'source' | 'preview') + }} borderOverride="border-muted" + disabledOptions={!canEdit ? ['source'] : []} + disabledOptionTooltip="Set up Custom SMTP to edit the source" /> {activeView === 'source' ? ( @@ -357,14 +372,15 @@ export const TemplateEditor = ({ template, isReadOnly = false }: TemplateEditorP Cancel )} - + )} diff --git a/apps/studio/components/ui/TwoOptionToggle.tsx b/apps/studio/components/ui/TwoOptionToggle.tsx index 4358e9a24b9..b439bc3e780 100644 --- a/apps/studio/components/ui/TwoOptionToggle.tsx +++ b/apps/studio/components/ui/TwoOptionToggle.tsx @@ -1,4 +1,4 @@ -import { cn } from 'ui' +import { cn, Tooltip, TooltipContent, TooltipTrigger } from 'ui' interface TwoOptionToggleProps { options: string[] @@ -6,6 +6,8 @@ interface TwoOptionToggleProps { activeOption: string onClickOption: (value: string) => void borderOverride: string + disabledOptions?: string[] + disabledOptionTooltip?: string } export const TwoOptionToggle = ({ @@ -14,6 +16,8 @@ export const TwoOptionToggle = ({ activeOption, onClickOption, borderOverride = 'border-stronger', + disabledOptions = [], + disabledOptionTooltip, }: TwoOptionToggleProps) => { const buttonStyle = ( isActive: boolean @@ -36,28 +40,43 @@ export const TwoOptionToggle = ({ 'transition-all ease-in-out border border-strong' )} /> - {options.map((option, index: number) => ( - onClickOption(option)} - > + {options.map((option, index: number) => { + const isDisabled = disabledOptions.includes(option) + const optionButton = ( { + if (!isDisabled) onClickOption(option) + }} > - {option} + + {option} + - - ))} + ) + + if (!isDisabled || !disabledOptionTooltip) return optionButton + + return ( + + {optionButton} + {disabledOptionTooltip} + + ) + })} ) }