Spaces:
Running
Running
In4ctividad
commited on
Update app/(main)/page.tsx
Browse files- app/(main)/page.tsx +34 -101
app/(main)/page.tsx
CHANGED
@@ -41,9 +41,7 @@ export default function Home() {
|
|
41 |
model: "",
|
42 |
});
|
43 |
let [ref, scrollTo] = useScrollTo();
|
44 |
-
let [messages, setMessages] = useState<{ role: string; content: string }[]>(
|
45 |
-
[],
|
46 |
-
);
|
47 |
|
48 |
let loading = status === "creating" || status === "updating";
|
49 |
|
@@ -57,41 +55,44 @@ export default function Home() {
|
|
57 |
setStatus("creating");
|
58 |
setGeneratedCode("");
|
59 |
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
|
|
74 |
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
|
79 |
-
|
80 |
-
|
81 |
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
|
|
|
|
86 |
}
|
87 |
-
receivedData += new TextDecoder().decode(value);
|
88 |
-
const cleanedData = removeCodeFormatting(receivedData);
|
89 |
-
setGeneratedCode(cleanedData);
|
90 |
-
}
|
91 |
|
92 |
-
|
93 |
-
|
94 |
-
|
|
|
|
|
|
|
|
|
95 |
}
|
96 |
|
97 |
useEffect(() => {
|
@@ -147,54 +148,9 @@ export default function Home() {
|
|
147 |
</button>
|
148 |
</div>
|
149 |
</div>
|
150 |
-
<div className="mt-6 flex flex-col justify-center gap-4 sm:flex-row sm:items-center sm:gap-8">
|
151 |
-
<div className="flex items-center justify-between gap-3 sm:justify-center">
|
152 |
-
<p className="text-gray-500 dark:text-gray-400 sm:text-xs">Model:</p>
|
153 |
-
<Select.Root
|
154 |
-
name="model"
|
155 |
-
disabled={loading}
|
156 |
-
value={model}
|
157 |
-
onValueChange={(value) => setModel(value)}
|
158 |
-
>
|
159 |
-
<Select.Trigger className="group flex w-60 max-w-xs items-center rounded-2xl border-[6px] border-gray-300 dark:border-gray-700 bg-white dark:bg-[#1E293B] px-4 py-2 text-sm focus-visible:outline focus-visible:outline-2 focus-visible:outline-blue-500">
|
160 |
-
<Select.Value />
|
161 |
-
<Select.Icon className="ml-auto">
|
162 |
-
<ChevronDownIcon className="size-6 text-gray-300 group-focus-visible:text-gray-500 group-enabled:group-hover:text-gray-500 dark:text-gray-600 dark:group-focus-visible:text-gray-400 dark:group-enabled:group-hover:text-gray-400" />
|
163 |
-
</Select.Icon>
|
164 |
-
</Select.Trigger>
|
165 |
-
<Select.Portal>
|
166 |
-
<Select.Content className="overflow-hidden rounded-md bg-white dark:bg-[#1E293B] shadow-lg">
|
167 |
-
<Select.Viewport className="p-2">
|
168 |
-
{models.map((model) => (
|
169 |
-
<Select.Item
|
170 |
-
key={model.value}
|
171 |
-
value={model.value}
|
172 |
-
className="flex cursor-pointer items-center rounded-md px-3 py-2 text-sm data-[highlighted]:bg-gray-100 dark:data-[highlighted]:bg-gray-800 data-[highlighted]:outline-none"
|
173 |
-
>
|
174 |
-
<Select.ItemText asChild>
|
175 |
-
<span className="inline-flex items-center gap-2 text-gray-500 dark:text-gray-400">
|
176 |
-
<div className="size-2 rounded-full bg-green-500" />
|
177 |
-
{model.label}
|
178 |
-
</span>
|
179 |
-
</Select.ItemText>
|
180 |
-
<Select.ItemIndicator className="ml-auto">
|
181 |
-
<CheckIcon className="size-5 text-blue-600" />
|
182 |
-
</Select.ItemIndicator>
|
183 |
-
</Select.Item>
|
184 |
-
))}
|
185 |
-
</Select.Viewport>
|
186 |
-
<Select.ScrollDownButton />
|
187 |
-
<Select.Arrow />
|
188 |
-
</Select.Content>
|
189 |
-
</Select.Portal>
|
190 |
-
</Select.Root>
|
191 |
-
</div>
|
192 |
-
</div>
|
193 |
</fieldset>
|
194 |
</form>
|
195 |
|
196 |
-
<hr className="border-1 mb-20 h-px bg-gray-700 dark:bg-gray-700/30" />
|
197 |
-
|
198 |
{status !== "initial" && (
|
199 |
<motion.div
|
200 |
initial={{ height: 0 }}
|
@@ -212,29 +168,6 @@ export default function Home() {
|
|
212 |
<div className="isolate">
|
213 |
<CodeViewer code={generatedCode} showEditor />
|
214 |
</div>
|
215 |
-
|
216 |
-
<AnimatePresence>
|
217 |
-
{loading && (
|
218 |
-
<motion.div
|
219 |
-
initial={status === "updating" ? { x: "100%" } : undefined}
|
220 |
-
animate={status === "updating" ? { x: "0%" } : undefined}
|
221 |
-
exit={{ x: "100%" }}
|
222 |
-
transition={{
|
223 |
-
type: "spring",
|
224 |
-
bounce: 0,
|
225 |
-
duration: 0.85,
|
226 |
-
delay: 0.5,
|
227 |
-
}}
|
228 |
-
className="absolute inset-x-0 bottom-0 top-1/2 flex items-center justify-center rounded-r border border-gray-400 dark:border-gray-700 bg-gradient-to-br from-gray-100 to-gray-300 dark:from-[#1E293B] dark:to-gray-800 md:inset-y-0 md:left-1/2 md:right-0"
|
229 |
-
>
|
230 |
-
<p className="animate-pulse text-3xl font-bold dark:text-gray-100">
|
231 |
-
{status === "creating"
|
232 |
-
? "Building your app..."
|
233 |
-
: "Updating your app..."}
|
234 |
-
</p>
|
235 |
-
</motion.div>
|
236 |
-
)}
|
237 |
-
</AnimatePresence>
|
238 |
</div>
|
239 |
</motion.div>
|
240 |
)}
|
|
|
41 |
model: "",
|
42 |
});
|
43 |
let [ref, scrollTo] = useScrollTo();
|
44 |
+
let [messages, setMessages] = useState<{ role: string; content: string }[]>([]);
|
|
|
|
|
45 |
|
46 |
let loading = status === "creating" || status === "updating";
|
47 |
|
|
|
55 |
setStatus("creating");
|
56 |
setGeneratedCode("");
|
57 |
|
58 |
+
try {
|
59 |
+
let res = await fetch("/api/generateCode", {
|
60 |
+
method: "POST",
|
61 |
+
headers: {
|
62 |
+
"Content-Type": "application/json",
|
63 |
+
},
|
64 |
+
body: JSON.stringify({
|
65 |
+
model,
|
66 |
+
messages: [{ role: "user", content: prompt }],
|
67 |
+
}),
|
68 |
+
});
|
69 |
+
|
70 |
+
if (!res.ok) {
|
71 |
+
throw new Error(res.statusText || `HTTP error: ${res.status}`);
|
72 |
+
}
|
73 |
|
74 |
+
if (!res.body) {
|
75 |
+
throw new Error("No response body");
|
76 |
+
}
|
77 |
|
78 |
+
const reader = res.body.getReader();
|
79 |
+
let receivedData = "";
|
80 |
|
81 |
+
while (true) {
|
82 |
+
const { done, value } = await reader.read();
|
83 |
+
if (done) break;
|
84 |
+
receivedData += new TextDecoder().decode(value);
|
85 |
+
const cleanedData = removeCodeFormatting(receivedData);
|
86 |
+
setGeneratedCode(cleanedData);
|
87 |
}
|
|
|
|
|
|
|
|
|
88 |
|
89 |
+
setMessages([{ role: "user", content: prompt }]);
|
90 |
+
setInitialAppConfig({ model });
|
91 |
+
setStatus("created");
|
92 |
+
} catch (error) {
|
93 |
+
console.error("Error al generar la aplicaci贸n:", error);
|
94 |
+
setStatus("initial");
|
95 |
+
}
|
96 |
}
|
97 |
|
98 |
useEffect(() => {
|
|
|
148 |
</button>
|
149 |
</div>
|
150 |
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
151 |
</fieldset>
|
152 |
</form>
|
153 |
|
|
|
|
|
154 |
{status !== "initial" && (
|
155 |
<motion.div
|
156 |
initial={{ height: 0 }}
|
|
|
168 |
<div className="isolate">
|
169 |
<CodeViewer code={generatedCode} showEditor />
|
170 |
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
171 |
</div>
|
172 |
</motion.div>
|
173 |
)}
|