EmptyRealtime.tsx106 lines · main
1import Link from 'next/link'
2import { AiIconAnimation, Button, Card, cn } from 'ui'
3
4import { AnimatedCursors } from './AnimatedCursors'
5import { SIDEBAR_KEYS } from '@/components/layouts/ProjectLayout/LayoutSidebar/LayoutSidebarProvider'
6import { DocsButton } from '@/components/ui/DocsButton'
7import { DOCS_URL } from '@/lib/constants'
8import { useAiAssistantStateSnapshot } from '@/state/ai-assistant-state'
9import { useSidebarManagerSnapshot } from '@/state/sidebar-manager-state'
10
11/**
12 * Acts as a container component for the entire log display
13 */
14export const EmptyRealtime = ({ projectRef }: { projectRef: string }) => {
15 const aiSnap = useAiAssistantStateSnapshot()
16 const { openSidebar } = useSidebarManagerSnapshot()
17
18 const handleCreateTriggerWithAssistant = () => {
19 openSidebar(SIDEBAR_KEYS.AI_ASSISTANT)
20 aiSnap.newChat({
21 name: `Realtime`,
22 initialInput: `Help me set up a realtime experience for my project`,
23 })
24 }
25
26 return (
27 <div className="flex grow items-center justify-center p-12 @container">
28 <div className="w-full max-w-4xl flex flex-col items-center gap-0">
29 <div className="text-center mb-12">
30 <AnimatedCursors />
31 <h2 className="heading-section mb-1">Create realtime experiences</h2>
32 <p className="text-foreground-light mb-6">
33 Send your first realtime message from your database, application code or edge function
34 </p>
35 <Button
36 type="default"
37 icon={<AiIconAnimation />}
38 onClick={handleCreateTriggerWithAssistant}
39 >
40 Set up realtime for me
41 </Button>
42 </div>
43
44 <Card className="grid grid-cols-1 @xl:grid-cols-3 bg divide-x mb-8">
45 <div className="flex flex-col h-full p-6">
46 <div className="flex items-center gap-3 mb-2">
47 <span
48 className={cn(
49 'text-xs shrink-0 font-mono text-foreground-light w-7 h-7 bg border flex items-center justify-center rounded-md'
50 )}
51 >
52 1
53 </span>
54 <h3 className="heading-default">Broadcast messages</h3>
55 </div>
56 <p className="text-foreground-light text-sm mb-4 flex-1">
57 Send messages to a channel from your client application or database via triggers.
58 </p>
59 <Button type="default" className="w-full">
60 <Link href={`/project/${projectRef}/database/triggers`}>Create a trigger</Link>
61 </Button>
62 </div>
63
64 <div className="flex flex-col h-full p-6">
65 <div className="flex items-center gap-3 mb-2">
66 <span
67 className={cn(
68 'text-xs shrink-0 font-mono text-foreground-light w-7 h-7 bg border flex items-center justify-center rounded-md'
69 )}
70 >
71 2
72 </span>
73 <h3 className="heading-default">Write policies</h3>
74 </div>
75 <p className="text-foreground-light text-sm mb-4 flex-1">
76 Set up Row Level Security policies to control who can see messages within a channel
77 </p>
78 <Button type="default">
79 <Link href={`/project/${projectRef}/realtime/policies`}>Write a policy</Link>
80 </Button>
81 </div>
82
83 <div className="flex flex-col h-full p-6">
84 <div className="flex items-center gap-3 mb-2">
85 <span
86 className={cn(
87 'text-xs shrink-0 font-mono text-foreground-light w-7 h-7 bg border flex items-center justify-center rounded-md'
88 )}
89 >
90 3
91 </span>
92 <h3 className="heading-default">Subscribe to a channel</h3>
93 </div>
94 <p className="text-foreground-light text-sm mb-4 flex-1">
95 Receive realtime messages in your application by listening to a channel
96 </p>
97 <DocsButton
98 abbrev={false}
99 href={`${DOCS_URL}/guides/realtime/subscribing-to-database-changes#listening-on-client-side`}
100 />
101 </div>
102 </Card>
103 </div>
104 </div>
105 )
106}