mirror of
https://github.com/simstudioai/sim.git
synced 2026-04-06 03:00:16 -04:00
feat(templates): create home templates
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
export { MessageContent } from './message-content'
|
||||
export { MothershipView } from './mothership-view'
|
||||
export { TemplatePrompts } from './template-prompts'
|
||||
export { UserInput } from './user-input'
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
export { TemplatePrompts } from './template-prompts'
|
||||
@@ -0,0 +1,94 @@
|
||||
import type { ComponentType, SVGProps } from 'react'
|
||||
import Image from 'next/image'
|
||||
import { Calendar, Search, Table } from '@/components/emcn/icons'
|
||||
import { GmailIcon } from '@/components/icons'
|
||||
import { MarkdownIcon } from '@/components/icons/document-icons'
|
||||
|
||||
interface TemplatePrompt {
|
||||
icon: ComponentType<SVGProps<SVGSVGElement>>
|
||||
title: string
|
||||
prompt: string
|
||||
image: string
|
||||
}
|
||||
|
||||
const TEMPLATES: TemplatePrompt[] = [
|
||||
{
|
||||
icon: Table,
|
||||
title: 'Self-populating CRM',
|
||||
prompt:
|
||||
'Create a self-healing CRM table that keeps track of all my customers by integrating with my existing data sources. Schedule a recurring job every morning to automatically pull updates from all relevant data sources and keep my CRM up to date.',
|
||||
image: '/templates/crm-light.png',
|
||||
},
|
||||
{
|
||||
icon: GmailIcon,
|
||||
title: 'Auto-reply agent',
|
||||
prompt: 'Create a Gmail agent that drafts responses to relevant emails automatically.',
|
||||
image: '/templates/gmail-agent-dark.png',
|
||||
},
|
||||
{
|
||||
icon: MarkdownIcon,
|
||||
title: 'Resolve todo list',
|
||||
prompt:
|
||||
'Create a file of all my todos then go one by one and check off every time a todo is done. Look at my calendar and see what I have to do.',
|
||||
image: '/templates/todo-list-light.png',
|
||||
},
|
||||
{
|
||||
icon: Search,
|
||||
title: 'Research assistant',
|
||||
prompt:
|
||||
'Build an agent that takes a topic, searches the web for the latest information, summarizes key findings, and compiles them into a clean document I can review.',
|
||||
image: '/templates/research-assistant-dark.png',
|
||||
},
|
||||
{
|
||||
icon: Calendar,
|
||||
title: 'Meeting prep agent',
|
||||
prompt:
|
||||
'Create an agent that checks my calendar each morning, pulls context on every attendee and topic, and prepares a brief for each meeting so I walk in fully prepared.',
|
||||
image: '/templates/meeting-prep-dark.png',
|
||||
},
|
||||
{
|
||||
icon: Table,
|
||||
title: 'Expense tracker',
|
||||
prompt:
|
||||
'Create a table that tracks all my expenses by pulling transactions from my connected accounts. Categorize each expense automatically and generate a weekly summary report.',
|
||||
image: '/templates/expense-tracker-light.png',
|
||||
},
|
||||
]
|
||||
|
||||
interface TemplatePromptsProps {
|
||||
onSelect: (prompt: string) => void
|
||||
}
|
||||
|
||||
export function TemplatePrompts({ onSelect }: TemplatePromptsProps) {
|
||||
return (
|
||||
<div className='grid grid-cols-3 gap-[12px]'>
|
||||
{TEMPLATES.map((template) => {
|
||||
const Icon = template.icon
|
||||
return (
|
||||
<button
|
||||
key={template.title}
|
||||
type='button'
|
||||
onClick={() => onSelect(template.prompt)}
|
||||
className='group flex cursor-pointer flex-col overflow-hidden rounded-[12px] border border-[var(--border-1)] bg-[var(--white)] text-left transition-colors hover:bg-[var(--surface-5)] dark:bg-[var(--surface-4)]'
|
||||
>
|
||||
<div className='relative h-[120px] overflow-hidden'>
|
||||
<Image
|
||||
src={template.image}
|
||||
alt={template.title}
|
||||
fill
|
||||
unoptimized
|
||||
className='object-cover transition-transform duration-300 group-hover:scale-105'
|
||||
/>
|
||||
</div>
|
||||
<div className='flex items-center gap-[8px] border-[var(--border-1)] border-t px-[12px] py-[10px]'>
|
||||
<Icon className='h-[14px] w-[14px] shrink-0 text-[var(--text-icon)]' />
|
||||
<span className='font-medium text-[14px] text-[var(--text-body)]'>
|
||||
{template.title}
|
||||
</span>
|
||||
</div>
|
||||
</button>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -16,7 +16,7 @@ import {
|
||||
import { persistImportedWorkflow } from '@/lib/workflows/operations/import-export'
|
||||
import { useChatHistory } from '@/hooks/queries/tasks'
|
||||
import { useSidebarStore } from '@/stores/sidebar/store'
|
||||
import { MessageContent, MothershipView, UserInput } from './components'
|
||||
import { MessageContent, MothershipView, TemplatePrompts, UserInput } from './components'
|
||||
import type { FileAttachmentForApi } from './components/user-input/user-input'
|
||||
import { useAutoScroll, useChat } from './hooks'
|
||||
|
||||
@@ -211,18 +211,24 @@ export function Home({ chatId }: HomeProps = {}) {
|
||||
|
||||
if (!hasMessages) {
|
||||
return (
|
||||
<div className='flex h-full flex-col items-center justify-center bg-[var(--bg)] px-[24px]'>
|
||||
<h1 className='mb-[24px] font-[450] font-season text-[32px] text-[var(--text-primary)] tracking-[-0.02em]'>
|
||||
What should we get done{session?.user?.name ? `, ${session.user.name.split(' ')[0]}` : ''}
|
||||
?
|
||||
</h1>
|
||||
<UserInput
|
||||
defaultValue={initialPrompt}
|
||||
onSubmit={handleSubmit}
|
||||
isSending={isSending}
|
||||
onStopGeneration={stopGeneration}
|
||||
userId={session?.user?.id}
|
||||
/>
|
||||
<div className='h-full overflow-y-auto bg-[var(--bg)]'>
|
||||
<div className='flex min-h-full flex-col items-center px-[24px]'>
|
||||
<div className='min-h-[30vh] flex-1' />
|
||||
<h1 className='mb-[24px] max-w-[42rem] font-[440] font-season text-[32px] text-[var(--text-primary)] tracking-[-0.02em]'>
|
||||
What should we get done
|
||||
{session?.user?.name ? `, ${session.user.name.split(' ')[0]}` : ''}?
|
||||
</h1>
|
||||
<UserInput
|
||||
defaultValue={initialPrompt}
|
||||
onSubmit={handleSubmit}
|
||||
isSending={isSending}
|
||||
onStopGeneration={stopGeneration}
|
||||
userId={session?.user?.id}
|
||||
/>
|
||||
<div className='w-full max-w-[42rem] pt-[48px] pb-[32px]'>
|
||||
<TemplatePrompts onSelect={(prompt) => handleSubmit(prompt)} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
BIN
apps/sim/public/templates/crm-light.png
Normal file
BIN
apps/sim/public/templates/crm-light.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 51 KiB |
BIN
apps/sim/public/templates/expense-tracker-light.png
Normal file
BIN
apps/sim/public/templates/expense-tracker-light.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 80 KiB |
BIN
apps/sim/public/templates/gmail-agent-dark.png
Normal file
BIN
apps/sim/public/templates/gmail-agent-dark.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 31 KiB |
BIN
apps/sim/public/templates/meeting-prep-dark.png
Normal file
BIN
apps/sim/public/templates/meeting-prep-dark.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 34 KiB |
BIN
apps/sim/public/templates/research-assistant-dark.png
Normal file
BIN
apps/sim/public/templates/research-assistant-dark.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 28 KiB |
BIN
apps/sim/public/templates/todo-list-light.png
Normal file
BIN
apps/sim/public/templates/todo-list-light.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 54 KiB |
Reference in New Issue
Block a user