Skip to content

Commit 43850d0

Browse files
committed
feat: add Clerk authentication pages, update Gemini models, and implement marketing workflow template with node execution status indicators
1 parent 21d35c1 commit 43850d0

16 files changed

Lines changed: 815 additions & 1059 deletions

File tree

app/api/workflows/route.ts

Lines changed: 184 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,189 @@ export async function POST(req: Request) {
3333
let edges: any[];
3434
let name = body.name ?? "Untitled Workflow";
3535

36-
if (body.template === "racing-car") {
36+
if (body.template === "sample-marketing") {
37+
name = "Marketing Workflow - Bluetooth Headphones";
38+
nodes = [
39+
{
40+
id: "request-inputs-1",
41+
type: "REQUEST_INPUTS",
42+
position: { x: 0, y: 250 },
43+
data: {
44+
label: "Request Inputs",
45+
config: {
46+
fields: [
47+
{
48+
name: "text_field",
49+
type: "text",
50+
value:
51+
"Product: Wireless Bluetooth Headphones. Features: Noise cancellation, 30-hour battery, foldable design.",
52+
},
53+
{
54+
name: "image_field",
55+
type: "image_field",
56+
value: "",
57+
},
58+
],
59+
},
60+
},
61+
deletable: false,
62+
selected: false,
63+
},
64+
{
65+
id: "crop-image-1",
66+
type: "CROP_IMAGE",
67+
position: { x: 380, y: 80 },
68+
data: {
69+
label: "Crop Image #1",
70+
config: { x: 20, y: 20, width: 60, height: 60 },
71+
},
72+
selected: false,
73+
},
74+
{
75+
id: "crop-image-2",
76+
type: "CROP_IMAGE",
77+
position: { x: 380, y: 350 },
78+
data: {
79+
label: "Crop Image #2",
80+
config: { x: 0, y: 0, width: 100, height: 50 },
81+
},
82+
selected: false,
83+
},
84+
{
85+
id: "gemini-1",
86+
type: "GEMINI",
87+
position: { x: 380, y: 550 },
88+
data: {
89+
label: "Gemini #1",
90+
config: {
91+
model: "gemini-2.0-flash-001",
92+
systemPrompt:
93+
"You are a marketing copywriter. Write a one-paragraph product description.",
94+
prompt: "{{text_field}}",
95+
temperature: 0.7,
96+
},
97+
},
98+
selected: false,
99+
},
100+
{
101+
id: "gemini-2",
102+
type: "GEMINI",
103+
position: { x: 760, y: 550 },
104+
data: {
105+
label: "Gemini #2",
106+
config: {
107+
model: "gemini-2.0-flash-001",
108+
systemPrompt:
109+
"Condense the following product description into a tweet-length hook (under 240 characters).",
110+
prompt: "{{response}}",
111+
temperature: 0.7,
112+
},
113+
},
114+
selected: false,
115+
},
116+
{
117+
id: "gemini-3",
118+
type: "GEMINI",
119+
position: { x: 1140, y: 250 },
120+
data: {
121+
label: "Final Gemini",
122+
config: {
123+
model: "gemini-2.0-flash-001",
124+
systemPrompt:
125+
"You are a social media manager. Combine the tweet hook and the two product crops into a final marketing post.",
126+
prompt: "{{response}}",
127+
temperature: 0.7,
128+
},
129+
},
130+
selected: false,
131+
},
132+
{
133+
id: "response-1",
134+
type: "RESPONSE",
135+
position: { x: 1520, y: 250 },
136+
data: {
137+
label: "Response",
138+
config: {},
139+
},
140+
deletable: false,
141+
selected: false,
142+
},
143+
];
144+
edges = [
145+
{
146+
id: "e-ri-crop1",
147+
source: "request-inputs-1",
148+
target: "crop-image-1",
149+
sourceHandle: "image_field",
150+
targetHandle: "inputImage",
151+
animated: true,
152+
},
153+
{
154+
id: "e-ri-crop2",
155+
source: "request-inputs-1",
156+
target: "crop-image-2",
157+
sourceHandle: "image_field",
158+
targetHandle: "inputImage",
159+
animated: true,
160+
},
161+
{
162+
id: "e-ri-gemini1",
163+
source: "request-inputs-1",
164+
target: "gemini-1",
165+
sourceHandle: "text_field",
166+
targetHandle: "prompt",
167+
animated: true,
168+
},
169+
{
170+
id: "e-gemini1-gemini2",
171+
source: "gemini-1",
172+
target: "gemini-2",
173+
sourceHandle: "response",
174+
targetHandle: "prompt",
175+
animated: true,
176+
},
177+
{
178+
id: "e-crop1-gemini3",
179+
source: "crop-image-1",
180+
target: "gemini-3",
181+
sourceHandle: "output",
182+
targetHandle: "imageVision",
183+
animated: true,
184+
},
185+
{
186+
id: "e-crop2-gemini3",
187+
source: "crop-image-2",
188+
target: "gemini-3",
189+
sourceHandle: "output",
190+
targetHandle: "imageVision",
191+
animated: true,
192+
},
193+
{
194+
id: "e-gemini2-gemini3",
195+
source: "gemini-2",
196+
target: "gemini-3",
197+
sourceHandle: "response",
198+
targetHandle: "prompt",
199+
animated: true,
200+
},
201+
{
202+
id: "e-gemini3-response",
203+
source: "gemini-3",
204+
target: "response-1",
205+
sourceHandle: "response",
206+
targetHandle: "result",
207+
animated: true,
208+
},
209+
{
210+
id: "e-crop2-response",
211+
source: "crop-image-2",
212+
target: "response-1",
213+
sourceHandle: "output",
214+
targetHandle: "result",
215+
animated: true,
216+
},
217+
];
218+
} else if (body.template === "racing-car") {
37219
name = "AI Racing Car Generator Copy";
38220
nodes = [
39221
{
@@ -56,7 +238,7 @@ export async function POST(req: Request) {
56238
data: {
57239
label: "Gemini",
58240
config: {
59-
model: "gemini-2.0-flash",
241+
model: "gemini-2.0-flash-001",
60242
prompt:
61243
"Generate a detailed image prompt or description for a racing car based on: {{Car prompt}}",
62244
temperature: 0.7,

app/app/flow/page.tsx

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,9 +73,15 @@ export default function FlowPage() {
7373
}
7474
}, []);
7575

76+
useEffect(() => {
77+
console.log(
78+
"[NextFlow] Candidate LinkedIn: https://www.linkedin.com/in/prashantvarma",
79+
);
80+
}, []);
81+
7682
useEffect(() => {
7783
if (isLoaded && !isSignedIn) {
78-
router.push("/");
84+
router.push("/sign-in");
7985
return;
8086
}
8187
if (isLoaded) fetchWorkflows();
@@ -193,7 +199,30 @@ export default function FlowPage() {
193199
</p>
194200

195201
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-8 max-w-[1300px]">
196-
{/* System template card */}
202+
{/* Sample marketing workflow */}
203+
<button
204+
type="button"
205+
onClick={() => createWorkflow("sample-marketing")}
206+
className="group text-left bg-white border border-gray-200 rounded-xl overflow-hidden hover:shadow-md transition-all cursor-pointer flex flex-col w-full"
207+
>
208+
<div className="aspect-[4/3] relative overflow-hidden bg-gradient-to-br from-indigo-600 via-purple-600 to-pink-500 w-full flex items-center justify-center">
209+
<div className="text-center text-white px-6">
210+
<div className="text-3xl font-black mb-1">7</div>
211+
<div className="text-xs font-bold uppercase tracking-widest opacity-80">
212+
Nodes
213+
</div>
214+
<div className="text-[10px] mt-2 opacity-60">
215+
Crop + Gemini + Response
216+
</div>
217+
</div>
218+
</div>
219+
<div className="bg-gray-50 py-4.5 text-center border-t border-gray-100 w-full">
220+
<span className="text-[16.5px] font-bold text-gray-900">
221+
Marketing Workflow
222+
</span>
223+
</div>
224+
</button>
225+
{/* Racing car template */}
197226
<button
198227
type="button"
199228
onClick={() => createWorkflow("racing-car")}

0 commit comments

Comments
 (0)