kalhdrawi commited on
Commit
a96208d
·
1 Parent(s): 9500400

Reupload OmniDev clean version

Browse files
components/editor/ask-ai/index.tsx CHANGED
@@ -16,6 +16,7 @@ import { ReImagine } from "@/components/editor/ask-ai/re-imagine";
16
  import { Selector } from "@/components/editor/ask-ai/selector";
17
  import { PromptBuilder } from "@/components/editor/ask-ai/prompt-builder";
18
  import { PromptEnhancer } from "@/components/editor/ask-ai/prompt-enhancer";
 
19
  import { useUser } from "@/hooks/useUser";
20
  import { useLoginModal } from "@/components/contexts/login-context";
21
  import { Settings } from "./settings";
@@ -290,6 +291,7 @@ export const AskAi = ({
290
  setEnhancedSettings={setEnhancedSettings}
291
  />
292
  <PromptEnhancer prompt={prompt} setPrompt={setPrompt} enhancedSettings={enhancedSettings!} />
 
293
  <Settings
294
  open={openProvider}
295
  error={providerError}
 
16
  import { Selector } from "@/components/editor/ask-ai/selector";
17
  import { PromptBuilder } from "@/components/editor/ask-ai/prompt-builder";
18
  import { PromptEnhancer } from "@/components/editor/ask-ai/prompt-enhancer";
19
+ import { HeroPresets } from "@/components/editor/hero-presets";
20
  import { useUser } from "@/hooks/useUser";
21
  import { useLoginModal } from "@/components/contexts/login-context";
22
  import { Settings } from "./settings";
 
291
  setEnhancedSettings={setEnhancedSettings}
292
  />
293
  <PromptEnhancer prompt={prompt} setPrompt={setPrompt} enhancedSettings={enhancedSettings!} />
294
+ <HeroPresets />
295
  <Settings
296
  open={openProvider}
297
  error={providerError}
components/editor/hero-presets/index.tsx ADDED
@@ -0,0 +1,59 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ "use client";
2
+ import { useState } from "react";
3
+ import { Button } from "@/components/ui/button";
4
+ import { Dialog, DialogContent, DialogFooter, DialogHeader, DialogTitle } from "@/components/ui/dialog";
5
+ import { HERO_TEMPLATES } from "@/lib/hero-templates";
6
+ import { useEditor } from "@/hooks/useEditor";
7
+
8
+ function insertIntoBody(html: string, snippet: string): string {
9
+ if (!html) return snippet;
10
+ const bodyOpen = html.toLowerCase().indexOf("<body");
11
+ if (bodyOpen === -1) return snippet + "\n" + html;
12
+ const afterBodyTag = html.indexOf(">", bodyOpen);
13
+ if (afterBodyTag === -1) return snippet + "\n" + html;
14
+ const head = html.slice(0, afterBodyTag + 1);
15
+ const tail = html.slice(afterBodyTag + 1);
16
+ return head + "\n" + snippet + "\n" + tail;
17
+ }
18
+
19
+ export function HeroPresets() {
20
+ const { currentPageData, setPages } = useEditor();
21
+ const [open, setOpen] = useState(false);
22
+ const [selected, setSelected] = useState<string | null>(null);
23
+
24
+ const apply = () => {
25
+ if (!selected) return;
26
+ const t = HERO_TEMPLATES.find(x => x.id === selected);
27
+ if (!t) return;
28
+ const newHtml = insertIntoBody(currentPageData.html, t.html);
29
+ setPages(prev => prev.map(p => p.path === currentPageData.path ? { ...p, html: newHtml } : p));
30
+ setOpen(false);
31
+ };
32
+
33
+ return (
34
+ <>
35
+ <Button size="xs" variant="outline" className="!rounded-md" onClick={() => setOpen(true)}>Hero Presets</Button>
36
+ <Dialog open={open} onOpenChange={setOpen}>
37
+ <DialogContent className="sm:max-w-3xl !bg-neutral-900 !border-neutral-800">
38
+ <DialogHeader>
39
+ <DialogTitle className="text-neutral-100">Insert Hero Template</DialogTitle>
40
+ </DialogHeader>
41
+ <div className="grid grid-cols-1 md:grid-cols-2 gap-3 max-h-[60vh] overflow-y-auto">
42
+ {HERO_TEMPLATES.map(t => (
43
+ <div key={t.id} className={`p-3 rounded-lg border cursor-pointer ${selected===t.id ? 'border-sky-500 bg-neutral-800/50' : 'border-neutral-800 bg-neutral-900/40'}`} onClick={() => setSelected(t.id)}>
44
+ <p className="font-medium text-neutral-200">{t.name}</p>
45
+ <p className="text-xs text-neutral-400">{t.id}</p>
46
+ <div className="mt-2 text-xs text-neutral-500 line-clamp-3">{t.html.slice(0, 200)}...</div>
47
+ </div>
48
+ ))}
49
+ </div>
50
+ <DialogFooter>
51
+ <Button size="sm" variant="bordered" onClick={() => setOpen(false)}>Close</Button>
52
+ <Button size="sm" onClick={apply} disabled={!selected}>Insert</Button>
53
+ </DialogFooter>
54
+ </DialogContent>
55
+ </Dialog>
56
+ </>
57
+ );
58
+ }
59
+
lib/hero-templates.ts ADDED
@@ -0,0 +1,207 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ export type HeroTemplateId =
2
+ | "animated-gradient"
3
+ | "particles"
4
+ | "waves"
5
+ | "noise"
6
+ | "parallax"
7
+ | "morphing-blobs"
8
+ | "rays"
9
+ | "grid"
10
+ | "shapes"
11
+ | "lines"
12
+ | "orbits";
13
+
14
+ export interface HeroTemplate {
15
+ id: HeroTemplateId;
16
+ name: string;
17
+ html: string; // full HTML snippet to insert inside <body>
18
+ }
19
+
20
+ export const HERO_TEMPLATES: HeroTemplate[] = [
21
+ {
22
+ id: "animated-gradient",
23
+ name: "Animated Gradient",
24
+ html: `
25
+ <!-- Hero: Animated Gradient -->
26
+ <section class="relative overflow-hidden min-h-[60vh] grid place-content-center text-center px-6 py-24">
27
+ <div class="absolute inset-0 bg-gradient-to-br from-sky-500/30 via-purple-500/20 to-pink-500/30 animate-[gradientMove_12s_ease_infinite] blur-3xl"></div>
28
+ <div class="relative z-10 max-w-3xl mx-auto">
29
+ <h1 class="text-4xl md:text-6xl font-extrabold tracking-tight text-white">Welcome to <span class="bg-clip-text text-transparent bg-gradient-to-r from-sky-400 to-purple-400">OmniDev</span></h1>
30
+ <p class="mt-4 text-neutral-300 text-lg">Build full-stack web projects with AI in minutes.</p>
31
+ <div class="mt-8 flex items-center justify-center gap-3">
32
+ <a href="#start" class="px-5 py-2.5 rounded-lg bg-white text-neutral-900 font-medium hover:opacity-90">Get Started</a>
33
+ <a href="#learn" class="px-5 py-2.5 rounded-lg bg-white/10 border border-white/20 text-white hover:bg-white/20">Learn More</a>
34
+ </div>
35
+ </div>
36
+ <style>
37
+ @keyframes gradientMove { 0%{transform:translateY(0)} 50%{transform:translateY(-20px)} 100%{transform:translateY(0)} }
38
+ </style>
39
+ </section>
40
+ `.trim(),
41
+ },
42
+ {
43
+ id: "waves",
44
+ name: "Waves",
45
+ html: `
46
+ <!-- Hero: Waves -->
47
+ <section class="relative overflow-hidden min-h-[60vh] grid place-content-center text-center px-6 py-24 bg-gradient-to-b from-neutral-900 to-neutral-950">
48
+ <svg class="absolute -bottom-10 left-0 w-[200%] opacity-40" viewBox="0 0 1440 320" xmlns="http://www.w3.org/2000/svg">
49
+ <path fill="#0ea5e9" fill-opacity="0.2" d="M0,64L48,74.7C96,85,192,107,288,122.7C384,139,480,149,576,176C672,203,768,245,864,229.3C960,213,1056,139,1152,128C1248,117,1344,171,1392,197.3L1440,224L1440,320L0,320Z" />
50
+ <path fill="#8b5cf6" fill-opacity="0.25" d="M0,96L60,117.3C120,139,240,181,360,192C480,203,600,181,720,160C840,139,960,117,1080,122.7C1200,128,1320,160,1380,176L1440,192L1440,320L0,320Z" />
51
+ </svg>
52
+ <div class="relative z-10 max-w-3xl mx-auto">
53
+ <h1 class="text-4xl md:text-6xl font-extrabold tracking-tight text-white">Beautiful Wave Hero</h1>
54
+ <p class="mt-4 text-neutral-300 text-lg">Effortless visuals with tailwind-only waves.</p>
55
+ </div>
56
+ </section>
57
+ `.trim(),
58
+ },
59
+ {
60
+ id: "noise",
61
+ name: "Noise Overlay",
62
+ html: `
63
+ <!-- Hero: Noise Overlay -->
64
+ <section class="relative overflow-hidden min-h-[60vh] grid place-content-center text-center px-6 py-24 bg-neutral-950">
65
+ <div class="absolute inset-0 bg-[radial-gradient(circle_at_20%_20%,rgba(14,165,233,0.2),transparent_50%),radial-gradient(circle_at_80%_30%,rgba(139,92,246,0.2),transparent_50%)]"></div>
66
+ <div class="absolute inset-0 opacity-[0.07]" style="background-image:url('data:image/svg+xml;utf8,<svg xmlns=\'http://www.w3.org/2000/svg\' width=\'160\' height=\'160\'><filter id=\'n\'><feTurbulence baseFrequency=\'0.65\' numOctaves=\'3\' stitchTiles=\'stitch\' /></filter><rect width=\'100%\' height=\'100%\' filter=\'url(%23n)\' /></svg>');"></div>
67
+ <div class="relative z-10 max-w-3xl mx-auto">
68
+ <h1 class="text-4xl md:text-6xl font-extrabold text-white">Noisy Hero</h1>
69
+ <p class="mt-4 text-neutral-300 text-lg">Subtle noise overlay for premium feel.</p>
70
+ </div>
71
+ </section>
72
+ `.trim(),
73
+ },
74
+ {
75
+ id: "parallax",
76
+ name: "Parallax Layers",
77
+ html: `
78
+ <!-- Hero: Parallax Layers -->
79
+ <section class="relative overflow-hidden min-h-[60vh] text-center px-6 py-24 bg-neutral-950">
80
+ <div class="absolute inset-0 pointer-events-none">
81
+ <div class="absolute inset-0 bg-gradient-to-b from-sky-500/10 to-purple-500/10"></div>
82
+ <div class="absolute -top-10 -left-10 w-64 h-64 bg-sky-500/20 rounded-full blur-3xl translate-y-4"></div>
83
+ <div class="absolute -bottom-10 -right-10 w-72 h-72 bg-purple-500/20 rounded-full blur-3xl -translate-y-4"></div>
84
+ </div>
85
+ <div class="relative z-10 max-w-3xl mx-auto">
86
+ <h1 class="text-4xl md:text-6xl font-extrabold text-white">Parallax Hero</h1>
87
+ <p class="mt-4 text-neutral-300 text-lg">Layered glow with depth illusion.</p>
88
+ </div>
89
+ </section>
90
+ `.trim(),
91
+ },
92
+ {
93
+ id: "morphing-blobs",
94
+ name: "Morphing Blobs",
95
+ html: `
96
+ <!-- Hero: Morphing Blobs -->
97
+ <section class="relative overflow-hidden min-h-[60vh] grid place-content-center text-center px-6 py-24 bg-neutral-950">
98
+ <svg class="absolute inset-0 w-full h-full opacity-20" viewBox="0 0 800 400" preserveAspectRatio="none">
99
+ <defs>
100
+ <linearGradient id="g" x1="0" x2="1" y1="0" y2="1">
101
+ <stop offset="0%" stop-color="#0ea5e9" />
102
+ <stop offset="100%" stop-color="#8b5cf6" />
103
+ </linearGradient>
104
+ </defs>
105
+ <path fill="url(#g)">
106
+ <animate attributeName="d" dur="12s" repeatCount="indefinite" values="
107
+ M0,320L80,288C160,256,320,192,480,165.3C640,139,800,149,960,154.7L960,400L0,400Z;
108
+ M0,320L120,261.3C240,203,480,85,720,101.3C960,117,1200,267,1440,288L1440,400L0,400Z;
109
+ M0,320L80,288C160,256,320,192,480,165.3C640,139,800,149,960,154.7L960,400L0,400Z" />
110
+ </path>
111
+ </svg>
112
+ <div class="relative z-10 max-w-3xl mx-auto">
113
+ <h1 class="text-4xl md:text-6xl font-extrabold tracking-tight text-white">Morphing Blobs Hero</h1>
114
+ <p class="mt-4 text-neutral-300 text-lg">SVG animated blobs with gradient.</p>
115
+ </div>
116
+ </section>
117
+ `.trim(),
118
+ },
119
+ {
120
+ id: "rays",
121
+ name: "Rays / Aurora",
122
+ html: `
123
+ <!-- Hero: Rays / Aurora -->
124
+ <section class="relative overflow-hidden min-h-[60vh] grid place-content-center text-center px-6 py-24 bg-neutral-950">
125
+ <div class="absolute inset-0" style="background: conic-gradient(from 90deg at 50% 50%, rgba(14,165,233,.15), rgba(139,92,246,.15), rgba(236,72,153,.15)); filter: blur(60px);"></div>
126
+ <div class="relative z-10 max-w-3xl mx-auto">
127
+ <h1 class="text-4xl md:text-6xl font-extrabold text-white">Aurora Hero</h1>
128
+ <p class="mt-4 text-neutral-300 text-lg">Conic gradient rays for an Aurora feel.</p>
129
+ </div>
130
+ </section>
131
+ `.trim(),
132
+ },
133
+ {
134
+ id: "grid",
135
+ name: "Animated Grid",
136
+ html: `
137
+ <!-- Hero: Animated Grid -->
138
+ <section class="relative overflow-hidden min-h-[60vh] grid place-content-center text-center px-6 py-24 bg-neutral-950">
139
+ <div class="absolute inset-0 bg-[linear-gradient(to_right,rgba(255,255,255,.07)_1px,transparent_1px),linear-gradient(to_bottom,rgba(255,255,255,.07)_1px,transparent_1px)] bg-[size:24px_24px]"></div>
140
+ <div class="absolute inset-0 animate-[pulse_6s_ease-in-out_infinite] bg-gradient-to-br from-white/5 to-transparent"></div>
141
+ <div class="relative z-10 max-w-3xl mx-auto">
142
+ <h1 class="text-4xl md:text-6xl font-extrabold text-white">Grid Hero</h1>
143
+ <p class="mt-4 text-neutral-300 text-lg">Animated grid with light sweep.</p>
144
+ </div>
145
+ </section>
146
+ `.trim(),
147
+ },
148
+ {
149
+ id: "shapes",
150
+ name: "Floating Shapes",
151
+ html: `
152
+ <!-- Hero: Floating Shapes -->
153
+ <section class="relative overflow-hidden min-h-[60vh] grid place-content-center text-center px-6 py-24">
154
+ <div class="absolute inset-0">
155
+ <div class="absolute left-10 top-10 w-8 h-8 rounded-full bg-sky-500/60 animate-[float_7s_ease-in-out_infinite]"></div>
156
+ <div class="absolute right-10 top-14 w-10 h-10 rounded-md bg-purple-500/60 animate-[float_9s_ease-in-out_infinite]"></div>
157
+ <div class="absolute left-1/2 bottom-10 w-12 h-12 rounded-lg bg-pink-500/60 animate-[float_6s_ease-in-out_infinite]"></div>
158
+ </div>
159
+ <div class="relative z-10 max-w-3xl mx-auto">
160
+ <h1 class="text-4xl md:text-6xl font-extrabold text-white">Floating Shapes</h1>
161
+ <p class="mt-4 text-neutral-300 text-lg">Gentle motion with CSS keyframes.</p>
162
+ </div>
163
+ <style>
164
+ @keyframes float { 0%{ transform: translateY(0)} 50%{ transform: translateY(-14px)} 100%{ transform: translateY(0)} }
165
+ </style>
166
+ </section>
167
+ `.trim(),
168
+ },
169
+ {
170
+ id: "lines",
171
+ name: "Moving Lines",
172
+ html: `
173
+ <!-- Hero: Moving Lines -->
174
+ <section class="relative overflow-hidden min-h-[60vh] grid place-content-center text-center px-6 py-24 bg-neutral-950">
175
+ <div class="absolute inset-0 bg-[repeating-linear-gradient(90deg,rgba(255,255,255,.06)_0,rgba(255,255,255,.06)_1px,transparent_1px,transparent_8px)] animate-[scrollX_20s_linear_infinite]"></div>
176
+ <div class="relative z-10 max-w-3xl mx-auto">
177
+ <h1 class="text-4xl md:text-6xl font-extrabold text-white">Moving Lines Hero</h1>
178
+ <p class="mt-4 text-neutral-300 text-lg">Subtle animated lines create motion.</p>
179
+ </div>
180
+ <style>
181
+ @keyframes scrollX { from{ background-position:0 0 } to{ background-position: 100% 0 } }
182
+ </style>
183
+ </section>
184
+ `.trim(),
185
+ },
186
+ {
187
+ id: "orbits",
188
+ name: "Orbits",
189
+ html: `
190
+ <!-- Hero: Orbits -->
191
+ <section class="relative overflow-hidden min-h-[60vh] grid place-content-center text-center px-6 py-24 bg-neutral-950">
192
+ <div class="absolute inset-0 grid place-content-center opacity-30">
193
+ <div class="relative w-64 h-64">
194
+ <div class="absolute inset-0 rounded-full border border-white/20"></div>
195
+ <div class="absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2 w-52 h-52 rounded-full border border-white/15"></div>
196
+ <div class="absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2 w-40 h-40 rounded-full border border-white/10"></div>
197
+ </div>
198
+ </div>
199
+ <div class="relative z-10 max-w-3xl mx-auto">
200
+ <h1 class="text-4xl md:text-6xl font-extrabold text-white">Orbit Hero</h1>
201
+ <p class="mt-4 text-neutral-300 text-lg">Concentric orbits with minimal styling.</p>
202
+ </div>
203
+ </section>
204
+ `.trim(),
205
+ },
206
+ ];
207
+