diff --git a/apps/sim/app/templates/[id]/template.tsx b/apps/sim/app/templates/[id]/template.tsx index f01c48cc6c..82383b102c 100644 --- a/apps/sim/app/templates/[id]/template.tsx +++ b/apps/sim/app/templates/[id]/template.tsx @@ -651,10 +651,10 @@ export default function TemplateDetails({ isWorkspaceContext = false }: Template className={cn( 'transition-colors', isStarred && - 'border-yellow-200 bg-yellow-50 text-yellow-700 hover:bg-yellow-100' + 'border-yellow-500/50 bg-yellow-500/10 text-yellow-500 hover:bg-yellow-500/20' )} > - + {starCount} )} @@ -837,14 +837,18 @@ export default function TemplateDetails({ isWorkspaceContext = false }: Template {/* Workflow preview */}
-

Workflow Preview

+

+ Workflow Preview +

{renderWorkflowPreview()}
{Array.isArray(template.requiredCredentials) && template.requiredCredentials.length > 0 && ( -
-

Credentials Needed

-
    +
    +

    + Credentials Needed +

    +
      {template.requiredCredentials.map((cred: CredentialRequirement, idx: number) => { // Get block name from registry or format blockType const blockName = @@ -862,97 +866,170 @@ export default function TemplateDetails({ isWorkspaceContext = false }: Template {/* About this Workflow */} {template.details?.about && ( -
      -

      About this Workflow

      -
      - {template.details.about} +
      +

      + About this Workflow +

      +
      + ( +

      + {children} +

      + ), + h1: ({ children }) => ( +

      + {children} +

      + ), + h2: ({ children }) => ( +

      + {children} +

      + ), + h3: ({ children }) => ( +

      + {children} +

      + ), + h4: ({ children }) => ( +

      + {children} +

      + ), + ul: ({ children }) => ( +
        + {children} +
      + ), + ol: ({ children }) => ( +
        + {children} +
      + ), + li: ({ children }) =>
    • {children}
    • , + code: ({ inline, children }: any) => + inline ? ( + + {children} + + ) : ( + + {children} + + ), + a: ({ href, children }) => ( + + {children} + + ), + strong: ({ children }) => ( + + {children} + + ), + em: ({ children }) => ( + {children} + ), + }} + > + {template.details.about} +
      )} {/* Creator Profile */} {template.creator && ( -
      -

      About the Creator

      -
      -
      - {/* Profile Picture */} -
      - {template.creator.profileImageUrl ? ( -
      - {template.creator.name} -
      - ) : ( -
      - -
      - )} -
      +
      +

      + About the Creator +

      +
      + {/* Profile Picture */} +
      + {template.creator.profileImageUrl ? ( +
      + {template.creator.name} +
      + ) : ( +
      + +
      + )} +
      - {/* Creator Info */} -
      -

      {template.creator.name}

      - {template.creator.details?.about && ( -

      - {template.creator.details.about} -

      - )} - - {/* Social Links */} - {(template.creator.details?.xUrl || - template.creator.details?.linkedinUrl || - template.creator.details?.websiteUrl || - template.creator.details?.contactEmail) && ( -
      - {template.creator.details.xUrl && ( - - - X - - )} - {template.creator.details.linkedinUrl && ( - - - LinkedIn - - )} - {template.creator.details.websiteUrl && ( - - - Website - - )} - {template.creator.details.contactEmail && ( - - - Contact - - )} -
      - )} -
      + {/* Creator Info */} +
      +

      + {template.creator.name} +

      + {template.creator.details?.about && ( +

      + {template.creator.details.about} +

      + )} + + {/* Social Links */} + {(template.creator.details?.xUrl || + template.creator.details?.linkedinUrl || + template.creator.details?.websiteUrl || + template.creator.details?.contactEmail) && ( +
      + {template.creator.details.xUrl && ( + + + X + + )} + {template.creator.details.linkedinUrl && ( + + + LinkedIn + + )} + {template.creator.details.websiteUrl && ( + + + Website + + )} + {template.creator.details.contactEmail && ( + + + Contact + + )} +
      + )}
      diff --git a/apps/sim/app/templates/components/template-card.tsx b/apps/sim/app/templates/components/template-card.tsx index 75e4b029d1..89ca38754d 100644 --- a/apps/sim/app/templates/components/template-card.tsx +++ b/apps/sim/app/templates/components/template-card.tsx @@ -337,8 +337,8 @@ export function TemplateCard({ className={cn( 'h-4 w-4 cursor-pointer transition-colors duration-50', localIsStarred - ? 'fill-yellow-400 text-yellow-400' - : 'text-muted-foreground hover:fill-yellow-400 hover:text-yellow-400', + ? 'fill-yellow-500 text-yellow-500' + : 'text-muted-foreground hover:fill-yellow-500 hover:text-yellow-500', isStarLoading && 'opacity-50' )} /> diff --git a/apps/sim/app/templates/template-card.tsx b/apps/sim/app/templates/template-card.tsx index c385b0d249..03f5d65234 100644 --- a/apps/sim/app/templates/template-card.tsx +++ b/apps/sim/app/templates/template-card.tsx @@ -460,8 +460,8 @@ export function TemplateCard({ className={cn( 'h-4 w-4 cursor-pointer transition-colors duration-50', localIsStarred - ? 'fill-yellow-400 text-yellow-400' - : 'text-muted-foreground hover:fill-yellow-400 hover:text-yellow-400', + ? 'fill-yellow-500 text-yellow-500' + : 'text-muted-foreground hover:fill-yellow-500 hover:text-yellow-500', isStarLoading && 'opacity-50' )} /> diff --git a/apps/sim/app/theme-provider.tsx b/apps/sim/app/theme-provider.tsx index 118bee9a42..c1f847bb07 100644 --- a/apps/sim/app/theme-provider.tsx +++ b/apps/sim/app/theme-provider.tsx @@ -7,24 +7,25 @@ import { ThemeProvider as NextThemesProvider } from 'next-themes' export function ThemeProvider({ children, ...props }: ThemeProviderProps) { const pathname = usePathname() - // Force dark mode for workspace pages + // Force dark mode for workspace pages and templates // Force light mode for certain public pages - const forcedTheme = pathname.startsWith('/workspace') - ? 'dark' - : pathname === '/' || - pathname.startsWith('/login') || - pathname.startsWith('/signup') || - pathname.startsWith('/sso') || - pathname.startsWith('/terms') || - pathname.startsWith('/privacy') || - pathname.startsWith('/invite') || - pathname.startsWith('/verify') || - pathname.startsWith('/careers') || - pathname.startsWith('/changelog') || - pathname.startsWith('/chat') || - pathname.startsWith('/studio') - ? 'light' - : undefined + const forcedTheme = + pathname.startsWith('/workspace') || pathname.startsWith('/templates') + ? 'dark' + : pathname === '/' || + pathname.startsWith('/login') || + pathname.startsWith('/signup') || + pathname.startsWith('/sso') || + pathname.startsWith('/terms') || + pathname.startsWith('/privacy') || + pathname.startsWith('/invite') || + pathname.startsWith('/verify') || + pathname.startsWith('/careers') || + pathname.startsWith('/changelog') || + pathname.startsWith('/chat') || + pathname.startsWith('/studio') + ? 'light' + : undefined return ( diff --git a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/control-bar/components/deploy-modal/components/template-deploy/template-deploy.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/control-bar/components/deploy-modal/components/template-deploy/template-deploy.tsx index 85bfa7be75..c78c4bf06f 100644 --- a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/control-bar/components/deploy-modal/components/template-deploy/template-deploy.tsx +++ b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/control-bar/components/deploy-modal/components/template-deploy/template-deploy.tsx @@ -78,33 +78,66 @@ export function TemplateDeploy({ workflowId, onDeploymentComplete }: TemplateDep }) // Fetch creator profiles - useEffect(() => { - const fetchCreatorOptions = async () => { - if (!session?.user?.id) return + const fetchCreatorOptions = async () => { + if (!session?.user?.id) return - setLoadingCreators(true) - try { - const response = await fetch('/api/creator-profiles') - if (response.ok) { - const data = await response.json() - const profiles = (data.profiles || []).map((profile: any) => ({ - id: profile.id, - name: profile.name, - referenceType: profile.referenceType, - referenceId: profile.referenceId, - })) - setCreatorOptions(profiles) - } - } catch (error) { - logger.error('Error fetching creator profiles:', error) - } finally { - setLoadingCreators(false) + setLoadingCreators(true) + try { + const response = await fetch('/api/creator-profiles') + if (response.ok) { + const data = await response.json() + const profiles = (data.profiles || []).map((profile: any) => ({ + id: profile.id, + name: profile.name, + referenceType: profile.referenceType, + referenceId: profile.referenceId, + })) + setCreatorOptions(profiles) + return profiles } + } catch (error) { + logger.error('Error fetching creator profiles:', error) + } finally { + setLoadingCreators(false) } + return [] + } + useEffect(() => { fetchCreatorOptions() }, [session?.user?.id]) + // Auto-select creator profile when there's only one option and no selection yet + useEffect(() => { + const currentCreatorId = form.getValues('creatorId') + if (creatorOptions.length === 1 && !currentCreatorId) { + form.setValue('creatorId', creatorOptions[0].id) + logger.info('Auto-selected single creator profile:', creatorOptions[0].name) + } + }, [creatorOptions, form]) + + // Listen for creator profile saved event + useEffect(() => { + const handleCreatorProfileSaved = async () => { + logger.info('Creator profile saved, refreshing profiles...') + + // Refetch creator profiles (autoselection will happen via the effect above) + await fetchCreatorOptions() + + // Close settings modal and reopen deploy modal to template tab + window.dispatchEvent(new CustomEvent('close-settings')) + setTimeout(() => { + window.dispatchEvent(new CustomEvent('open-deploy-modal', { detail: { tab: 'template' } })) + }, 100) + } + + window.addEventListener('creator-profile-saved', handleCreatorProfileSaved) + + return () => { + window.removeEventListener('creator-profile-saved', handleCreatorProfileSaved) + } + }, []) + // Check for existing template useEffect(() => { const checkExistingTemplate = async () => { @@ -454,12 +487,12 @@ export function TemplateDeploy({ workflowId, onDeploymentComplete }: TemplateDep )} {/* Template State Preview Dialog */} - {showPreviewDialog && ( - - - - Template State Preview - + + + + Published Template Preview + + {showPreviewDialog && (
      {(() => { if (!existingTemplate?.state || !existingTemplate.state.blocks) { @@ -487,7 +520,7 @@ export function TemplateDeploy({ workflowId, onDeploymentComplete }: TemplateDep return (
      - -
      - )} + )} +
      +
      ) } diff --git a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/control-bar/components/deploy-modal/deploy-modal.tsx b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/control-bar/components/deploy-modal/deploy-modal.tsx index 63783b55cc..7734a43a57 100644 --- a/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/control-bar/components/deploy-modal/deploy-modal.tsx +++ b/apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/control-bar/components/deploy-modal/deploy-modal.tsx @@ -445,6 +445,23 @@ export function DeployModal({ } }, [open, selectedStreamingOutputs, setSelectedStreamingOutputs]) + // Listen for event to reopen deploy modal + useEffect(() => { + const handleOpenDeployModal = (event: Event) => { + const customEvent = event as CustomEvent<{ tab?: TabView }> + onOpenChange(true) + if (customEvent.detail?.tab) { + setActiveTab(customEvent.detail.tab) + } + } + + window.addEventListener('open-deploy-modal', handleOpenDeployModal) + + return () => { + window.removeEventListener('open-deploy-modal', handleOpenDeployModal) + } + }, [onOpenChange]) + const handleActivateVersion = (version: number) => { setVersionToActivate(version) setActiveTab('api') diff --git a/apps/sim/app/workspace/[workspaceId]/w/components/sidebar/components-new/settings-modal/components/components/creator-profile/creator-profile.tsx b/apps/sim/app/workspace/[workspaceId]/w/components/sidebar/components-new/settings-modal/components/components/creator-profile/creator-profile.tsx index d38b38cc3f..1a3a89afc4 100644 --- a/apps/sim/app/workspace/[workspaceId]/w/components/sidebar/components-new/settings-modal/components/components/creator-profile/creator-profile.tsx +++ b/apps/sim/app/workspace/[workspaceId]/w/components/sidebar/components-new/settings-modal/components/components/creator-profile/creator-profile.tsx @@ -196,7 +196,9 @@ export function CreatorProfile() { logger.info('Creator profile saved successfully') setSaveStatus('saved') - // Reset to idle after 2 seconds + // Dispatch event to notify that a creator profile was saved + window.dispatchEvent(new CustomEvent('creator-profile-saved')) + setTimeout(() => { setSaveStatus('idle') }, 2000) diff --git a/apps/sim/app/workspace/[workspaceId]/w/components/sidebar/components-new/settings-modal/settings-modal.tsx b/apps/sim/app/workspace/[workspaceId]/w/components/sidebar/components-new/settings-modal/settings-modal.tsx index 35ae3ca431..9a77c111b3 100644 --- a/apps/sim/app/workspace/[workspaceId]/w/components/sidebar/components-new/settings-modal/settings-modal.tsx +++ b/apps/sim/app/workspace/[workspaceId]/w/components/sidebar/components-new/settings-modal/settings-modal.tsx @@ -90,10 +90,16 @@ export function SettingsModal({ open, onOpenChange }: SettingsModalProps) { onOpenChange(true) } + const handleCloseSettings = () => { + onOpenChange(false) + } + window.addEventListener('open-settings', handleOpenSettings as EventListener) + window.addEventListener('close-settings', handleCloseSettings as EventListener) return () => { window.removeEventListener('open-settings', handleOpenSettings as EventListener) + window.removeEventListener('close-settings', handleCloseSettings as EventListener) } }, [onOpenChange])