Skip to content

Commit 3b2f60f

Browse files
committed
feat (tasks/integrations): added new effect to tasks and integrations pages
1 parent 025e101 commit 3b2f60f

8 files changed

Lines changed: 161 additions & 14 deletions

File tree

src/client/app/integrations/page.js

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ import {
3838
} from "@tabler/icons-react"
3939
import { cn } from "@utils/cn"
4040
import { usePostHog } from "posthog-js/react"
41+
import InteractiveNetworkBackground from "@components/ui/InteractiveNetworkBackground"
4142
import { motion, AnimatePresence } from "framer-motion"
4243
import {
4344
MorphingDialog,
@@ -581,15 +582,15 @@ const IntegrationCard = ({ integration, icon: Icon }) => {
581582
integration.connected || integration.auth_type === "builtin"
582583

583584
return (
584-
<div className="bg-neutral-900/50 p-5 rounded-xl transition-all duration-300 border border-neutral-800/70 hover:border-brand-orange hover:-translate-y-1 flex flex-col text-left h-full">
585+
<div className="bg-neutral-900/50 p-4 sm:p-5 rounded-xl transition-all duration-300 border border-neutral-800/70 hover:border-brand-orange hover:-translate-y-1 flex flex-col text-left h-full">
585586
{/* Top Section */}
586587
<div className="flex items-start justify-between mb-4">
587588
<div className="flex items-center gap-3">
588589
<div className="w-10 h-10 flex items-center justify-center rounded-lg bg-brand-gray p-1.5 text-brand-orange">
589590
<Icon className="w-full h-full" />
590591
</div>
591592
<div>
592-
<h3 className="font-semibold text-white text-lg">
593+
<h3 className="font-semibold text-white text-base sm:text-lg">
593594
{integration.display_name}
594595
</h3>
595596
<span
@@ -942,16 +943,23 @@ const IntegrationsPage = () => {
942943
}, [allIntegrations, searchQuery, activeCategory])
943944

944945
return (
945-
<div className="flex-1 flex h-screen bg-dark-surface text-white overflow-x-hidden">
946+
<div className="flex-1 flex h-screen text-white overflow-x-hidden">
946947
<Tooltip
947948
id="page-help-tooltip"
948949
place="right-start"
949950
style={{ zIndex: 9999 }}
950951
/>
951952
<SparkleEffect trigger={sparkleTrigger} />
952-
<div className="flex-1 flex flex-col overflow-hidden relative bg-dark-surface md:pl-20 pb-16 md:pb-0">
953+
<div
954+
className={cn(
955+
"flex-1 flex flex-col overflow-hidden relative w-full md:pl-20 pb-16 md:pb-0"
956+
)}
957+
>
958+
<div className="absolute inset-0 z-[-1] network-grid-background">
959+
<InteractiveNetworkBackground />
960+
</div>
953961
<div className="absolute -top-[250px] left-1/2 -translate-x-1/2 w-[800px] h-[500px] bg-brand-orange/10 rounded-full blur-3xl -z-10" />
954-
<header className="flex items-center justify-between p-4 sm:p-6 md:px-8 md:py-6 bg-dark-surface border-b border-[var(--color-primary-surface)] shrink-0">
962+
<header className="flex items-center justify-between p-4 sm:p-6 md:px-8 md:py-6 bg-transparent border-b border-[var(--color-primary-surface)] shrink-0">
955963
<HelpTooltip content="Connect your apps here. This allows Sentient to access information and perform actions on your behalf." />
956964
<div>
957965
<h1 className="text-3xl lg:text-4xl font-bold text-white">
@@ -1054,13 +1062,13 @@ const IntegrationsPage = () => {
10541062
<MorphingDialogContainer>
10551063
<MorphingDialogContent className="pointer-events-auto relative flex h-auto w-full flex-col overflow-hidden border border-neutral-700 bg-neutral-900 sm:w-[600px] rounded-2xl">
10561064
<BorderTrail className="bg-brand-orange" />
1057-
<div className="p-6 overflow-y-auto custom-scrollbar">
1065+
<div className="p-4 sm:p-6 overflow-y-auto custom-scrollbar">
10581066
<div className="flex items-center gap-4 mb-4">
10591067
<div className="w-10 h-10 flex items-center justify-center rounded-lg bg-brand-gray p-1.5 text-brand-orange">
10601068
<Icon className="w-full h-full" />
10611069
</div>
10621070
<div>
1063-
<MorphingDialogTitle className="text-2xl font-bold text-white">
1071+
<MorphingDialogTitle className="text-xl sm:text-2xl font-bold text-white">
10641072
{
10651073
integration.display_name
10661074
}
@@ -1073,7 +1081,7 @@ const IntegrationsPage = () => {
10731081
</div>
10741082
</div>
10751083
<MorphingDialogDescription>
1076-
<p className="text-neutral-300 mb-6">
1084+
<p className="text-sm sm:text-base text-neutral-300 mb-6">
10771085
{
10781086
integration.description
10791087
}

src/client/app/tasks/page.js

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import ListView from "@components/tasks/ListView"
2222
import CalendarView from "@components/tasks/CalendarView"
2323
import WelcomePanel from "@components/tasks/WelcomePanel"
2424
import CreateTaskInput from "@components/tasks/CreateTaskInput"
25+
import InteractiveNetworkBackground from "@components/ui/InteractiveNetworkBackground"
2526
import DayDetailView from "@components/tasks/DayDetailView"
2627

2728
function TasksPageContent() {
@@ -264,7 +265,10 @@ function TasksPageContent() {
264265
place="right"
265266
style={{ zIndex: 9999 }}
266267
/>
267-
<div className="flex-1 flex flex-col md:flex-row ml-2 gap-x-2 overflow-hidden">
268+
<div className="flex-1 flex flex-col md:flex-row ml-2 gap-x-2 overflow-hidden relative">
269+
<div className="absolute inset-0 z-[-1] network-grid-background">
270+
<InteractiveNetworkBackground />
271+
</div>
268272
{/* Main Content Panel */}
269273
<main className="flex-1 flex flex-col overflow-hidden relative">
270274
<div className="absolute -top-[250px] left-1/2 -translate-x-1/2 w-[800px] h-[500px] bg-brand-orange/10 rounded-full blur-3xl -z-10" />
@@ -323,7 +327,7 @@ function TasksPageContent() {
323327
</main>
324328

325329
{/* Right Details Panel */}
326-
<aside className="w-full md:w-[450px] lg:w-[500px] bg-brand-black border-l border-brand-gray flex-shrink-0 flex flex-col">
330+
<aside className="w-full md:w-[450px] lg:w-[500px] bg-brand-black/50 backdrop-blur-sm border-l border-brand-gray flex-shrink-0 flex flex-col">
327331
<AnimatePresence mode="wait">
328332
{rightPanelContent.type === "task" &&
329333
rightPanelContent.data ? (

src/client/components/tasks/CalendarView.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ const CalendarDayCell = ({
4949
variants={cellVariants}
5050
className={cn(
5151
"border-r border-b border-neutral-800 p-2 flex flex-col gap-1 overflow-hidden relative min-h-[120px] rounded-lg",
52-
!isCurrentMonth && "bg-brand-black text-neutral-600",
52+
!isCurrentMonth && "bg-neutral-900/50 text-neutral-600",
5353
isSelected
5454
? "bg-brand-orange/90 text-brand-black font-bold hover:bg-brand-orange"
5555
: "hover:bg-neutral-800/70"

src/client/components/tasks/ListView.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ const ListView = ({
5858
}
5959

6060
return (
61-
<div className="p-6 space-y-4 overflow-y-auto custom-scrollbar h-full bg-brand-black/50 backdrop-blur-sm rounded-xl border border-zinc-700/50">
61+
<div className="p-6 space-y-4 overflow-y-auto custom-scrollbar h-full bg-transparent rounded-xl">
6262
<div className="relative">
6363
<IconSearch
6464
className="absolute left-3 top-1/2 -translate-y-1/2 text-neutral-500"

src/client/components/tasks/TaskCardList.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ const TaskCardList = ({ task, onSelectTask }) => {
5151
variants={cardVariants}
5252
exit={{ opacity: 0, transition: { duration: 0.1 } }}
5353
onClick={() => onSelectTask(task)}
54-
className="bg-brand-black p-4 rounded-lg border border-zinc-700 hover:border-brand-orange transition-all cursor-pointer relative"
54+
className="bg-neutral-900/50 p-4 rounded-lg border border-zinc-700 hover:border-brand-orange transition-all cursor-pointer relative"
5555
>
5656
<div className="flex justify-between items-start gap-4">
5757
<p className="font-sans font-semibold text-brand-white flex-1 text-sm">
Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
// src/client/components/ui/InteractiveNetworkBackground.js
2+
"use client"
3+
import React, { useRef, useEffect } from "react"
4+
import { cn } from "@utils/cn"
5+
6+
const InteractiveNetworkBackground = ({ className }) => {
7+
const canvasRef = useRef(null)
8+
9+
useEffect(() => {
10+
const canvas = canvasRef.current
11+
if (!canvas) return
12+
13+
const ctx = canvas.getContext("2d")
14+
let animationFrameId
15+
let time = 0
16+
17+
// Disable on mobile for performance
18+
if (window.innerWidth < 768) {
19+
return
20+
}
21+
22+
const setup = () => {
23+
canvas.width = window.innerWidth
24+
canvas.height = window.innerHeight
25+
}
26+
27+
const particles = []
28+
const particleCount = 150
29+
const connectionDistance = 150
30+
31+
class Particle {
32+
constructor() {
33+
this.x = Math.random() * canvas.width
34+
this.y = Math.random() * canvas.height
35+
this.vx = (Math.random() - 0.5) * 0.5
36+
this.vy = (Math.random() - 0.5) * 0.5
37+
this.radius = 1.5
38+
this.pulseOffset = Math.random() * Math.PI * 2
39+
}
40+
41+
update() {
42+
if (this.x < 0 || this.x > canvas.width) this.vx *= -1
43+
if (this.y < 0 || this.y > canvas.height) this.vy *= -1
44+
this.x += this.vx
45+
this.y += this.vy
46+
}
47+
48+
draw() {
49+
const pulseRadius =
50+
this.radius + Math.sin(time * 0.05 + this.pulseOffset) * 0.5
51+
ctx.beginPath()
52+
ctx.arc(this.x, this.y, pulseRadius, 0, Math.PI * 2)
53+
ctx.fillStyle = "rgba(241, 162, 29, 0.5)"
54+
ctx.fill()
55+
}
56+
}
57+
58+
const init = () => {
59+
particles.length = 0
60+
for (let i = 0; i < particleCount; i++) {
61+
particles.push(new Particle())
62+
}
63+
}
64+
65+
const animate = () => {
66+
time++
67+
ctx.clearRect(0, 0, canvas.width, canvas.height)
68+
particles.forEach((p) => {
69+
p.update()
70+
p.draw()
71+
})
72+
connect()
73+
animationFrameId = requestAnimationFrame(animate)
74+
}
75+
76+
const connect = () => {
77+
for (let i = 0; i < particles.length; i++) {
78+
for (let j = i + 1; j < particles.length; j++) {
79+
const distance = Math.sqrt(
80+
Math.pow(particles[i].x - particles[j].x, 2) +
81+
Math.pow(particles[i].y - particles[j].y, 2)
82+
)
83+
if (distance < connectionDistance) {
84+
const opacity = 1 - distance / connectionDistance
85+
ctx.strokeStyle = `rgba(241, 162, 29, ${opacity})`
86+
ctx.lineWidth = 0.7
87+
ctx.beginPath()
88+
ctx.moveTo(particles[i].x, particles[i].y)
89+
ctx.lineTo(particles[j].x, particles[j].y)
90+
ctx.stroke()
91+
}
92+
}
93+
}
94+
}
95+
96+
const handleResize = () => {
97+
setup()
98+
init()
99+
}
100+
101+
setup()
102+
init()
103+
animate()
104+
105+
window.addEventListener("resize", handleResize)
106+
107+
return () => {
108+
window.removeEventListener("resize", handleResize)
109+
cancelAnimationFrame(animationFrameId)
110+
}
111+
}, [])
112+
113+
return (
114+
<canvas
115+
ref={canvasRef}
116+
className={cn("absolute inset-0 z-[-1] opacity-30", className)}
117+
aria-hidden="true"
118+
/>
119+
)
120+
}
121+
122+
export default InteractiveNetworkBackground

src/client/components/ui/morphing-dialog.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,7 @@ function MorphingDialogContainer({ children }) {
190190
animate={{ opacity: 1 }}
191191
exit={{ opacity: 0 }}
192192
/>
193-
<div className="fixed inset-0 z-50 flex items-center justify-center">
193+
<div className="fixed inset-0 z-50 flex items-center justify-center p-4">
194194
{children}
195195
</div>
196196
</>

src/client/styles/globals.css

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,3 +120,16 @@ button,
120120
.sparkle-on-complete {
121121
animation: sparkle 1.5s ease-in-out;
122122
}
123+
124+
.network-grid-background {
125+
background-color: var(--color-primary-background); /* Or #000000 */
126+
background-image:
127+
linear-gradient(rgba(241, 162, 29, 0.05) 1px, transparent 1px),
128+
linear-gradient(to right, rgba(241, 162, 29, 0.05) 1px, transparent 1px);
129+
background-size: 40px 40px;
130+
mask-image: radial-gradient(
131+
ellipse 100% 80% at 50% 50%,
132+
black,
133+
transparent 95%
134+
);
135+
}

0 commit comments

Comments
 (0)