Refactor to next.js app

This commit is contained in:
Laurie Voss
2025-07-15 14:39:50 -07:00
parent c57ebf3e32
commit 95ba2c63b3
21 changed files with 2148 additions and 2663 deletions
+3
View File
@@ -22,3 +22,6 @@ dist-ssr
*.njsproj
*.sln
*.sw?
# next things
.next
View File
+23
View File
@@ -0,0 +1,23 @@
import type { Metadata } from "next";
import { Inter } from "next/font/google";
import React from "react";
import "./globals.css";
const inter = Inter({ subsets: ["latin"] });
export const metadata: Metadata = {
title: "Llama Agent Creator",
description: "A tool for creating and managing Llama agents",
};
export default function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
return (
<html lang="en">
<body className={inter.className}>{children}</body>
</html>
);
}
+29 -27
View File
@@ -1,27 +1,29 @@
import { useLocation } from "react-router-dom";
import { useEffect } from "react";
const NotFound = () => {
const location = useLocation();
useEffect(() => {
console.error(
"404 Error: User attempted to access non-existent route:",
location.pathname
);
}, [location.pathname]);
return (
<div className="min-h-screen flex items-center justify-center bg-gray-100">
<div className="text-center">
<h1 className="text-4xl font-bold mb-4">404</h1>
<p className="text-xl text-gray-600 mb-4">Oops! Page not found</p>
<a href="/" className="text-blue-500 hover:text-blue-700 underline">
Return to Home
</a>
</div>
</div>
);
};
export default NotFound;
'use client';
import { useEffect } from "react";
import { usePathname } from 'next/navigation';
const NotFound = () => {
const pathname = usePathname();
useEffect(() => {
console.error(
"404 Error: User attempted to access non-existent route:",
pathname
);
}, [pathname]);
return (
<div className="min-h-screen flex items-center justify-center bg-gray-100">
<div className="text-center">
<h1 className="text-4xl font-bold mb-4">404</h1>
<p className="text-xl text-gray-600 mb-4">Oops! Page not found</p>
<a href="/" className="text-blue-500 hover:text-blue-700 underline">
Return to Home
</a>
</div>
</div>
);
};
export default NotFound;
+15 -4
View File
@@ -1,9 +1,21 @@
"use client";
import { useState } from "react";
import AgentFlow from "@/components/AgentFlow";
import RunView from "@/components/RunView";
import { Button } from "@/components/ui/button";
import {
ResizableHandle,
ResizablePanel,
ResizablePanelGroup,
} from "@/components/ui/resizable";
import { Separator } from "@/components/ui/separator";
import { Sidebar } from "@/components/ui/sidebar";
import { Toaster } from "@/components/ui/toaster";
import { useIsMobile } from "@/hooks/use-mobile";
const Index = () => {
export default function IndexPage() {
const isMobile = useIsMobile();
const [isSidebarOpen, setIsSidebarOpen] = useState(true);
const [activeTab, setActiveTab] = useState<'edit' | 'run'>('edit');
return (
@@ -30,8 +42,7 @@ const Index = () => {
<div style={{ height: 'calc(100vh - 3rem)' }}>
{activeTab === 'edit' ? <AgentFlow /> : <RunView />}
</div>
<Toaster />
</div>
);
};
export default Index;
}
BIN
View File
Binary file not shown.
-24
View File
@@ -1,24 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>llamazon-agent-flow</title>
<meta name="description" content="Lovable Generated Project" />
<meta name="author" content="Lovable" />
<meta property="og:title" content="llamazon-agent-flow" />
<meta property="og:description" content="Lovable Generated Project" />
<meta property="og:type" content="website" />
<meta property="og:image" content="https://lovable.dev/opengraph-image-p98pqg.png" />
<meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:site" content="@lovable_dev" />
<meta name="twitter:image" content="https://lovable.dev/opengraph-image-p98pqg.png" />
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
</body>
</html>
+5
View File
@@ -0,0 +1,5 @@
/// <reference types="next" />
/// <reference types="next/image-types/global" />
// NOTE: This file should not be edited
// see https://nextjs.org/docs/basic-features/typescript for more information.
+2033 -2419
View File
File diff suppressed because it is too large Load Diff
+6 -10
View File
@@ -2,13 +2,11 @@
"name": "vite_react_shadcn_ts",
"private": true,
"version": "0.0.0",
"type": "module",
"scripts": {
"dev": "vite",
"build": "vite build",
"build:dev": "vite build --mode development",
"lint": "eslint .",
"preview": "vite preview"
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "next lint"
},
"dependencies": {
"@hookform/resolvers": "^3.9.0",
@@ -49,12 +47,12 @@
"input-otp": "^1.2.4",
"lucide-react": "^0.462.0",
"next-themes": "^0.3.0",
"next": "14.2.5",
"react": "^18.3.1",
"react-day-picker": "^8.10.1",
"react-dom": "^18.3.1",
"react-hook-form": "^7.53.0",
"react-resizable-panels": "^2.1.3",
"react-router-dom": "^6.26.2",
"recharts": "^2.12.7",
"sonner": "^1.5.0",
"tailwind-merge": "^2.5.2",
@@ -77,8 +75,6 @@
"lovable-tagger": "^1.1.7",
"postcss": "^8.4.47",
"tailwindcss": "^3.4.11",
"typescript": "^5.5.3",
"typescript-eslint": "^8.0.1",
"vite": "^5.4.1"
"typescript": "^5.5.3"
}
}
+2 -2
View File
@@ -1,6 +1,6 @@
export default {
module.exports = {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
}
};
-42
View File
@@ -1,42 +0,0 @@
#root {
max-width: 1280px;
margin: 0 auto;
padding: 2rem;
text-align: center;
}
.logo {
height: 6em;
padding: 1.5em;
will-change: filter;
transition: filter 300ms;
}
.logo:hover {
filter: drop-shadow(0 0 2em #646cffaa);
}
.logo.react:hover {
filter: drop-shadow(0 0 2em #61dafbaa);
}
@keyframes logo-spin {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
@media (prefers-reduced-motion: no-preference) {
a:nth-of-type(2) .logo {
animation: logo-spin infinite 20s linear;
}
}
.card {
padding: 2em;
}
.read-the-docs {
color: #888;
}
-27
View File
@@ -1,27 +0,0 @@
import { Toaster } from "@/components/ui/toaster";
import { Toaster as Sonner } from "@/components/ui/sonner";
import { TooltipProvider } from "@/components/ui/tooltip";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { BrowserRouter, Routes, Route } from "react-router-dom";
import Index from "./pages/Index";
import NotFound from "./pages/NotFound";
const queryClient = new QueryClient();
const App = () => (
<QueryClientProvider client={queryClient}>
<TooltipProvider>
<Toaster />
<Sonner />
<BrowserRouter>
<Routes>
<Route path="/" element={<Index />} />
{/* ADD ALL CUSTOM ROUTES ABOVE THE CATCH-ALL "*" ROUTE */}
<Route path="*" element={<NotFound />} />
</Routes>
</BrowserRouter>
</TooltipProvider>
</QueryClientProvider>
);
export default App;
+7 -2
View File
@@ -87,6 +87,11 @@ const AgentFlowInner = () => {
const { screenToFlowPosition } = useReactFlow();
const reactFlowWrapper = useRef<HTMLDivElement>(null);
// onUpdateSettings sets the settings
const onUpdateSettings = (newSettings: SettingsData) => {
setSettings(newSettings);
};
// Load settings from localStorage on mount
useEffect(() => {
try {
@@ -263,7 +268,7 @@ const AgentFlowInner = () => {
)}
</div>
<AgentBuilderSidebar onAddNode={onAddNode} onReset={onReset} settings={settings} onUpdateSettings={setSettings} />
<AgentBuilderSidebar onAddNode={onAddNode} onReset={onReset} settings={settings} onUpdateSettings={onUpdateSettings} />
<div className="flex-1" ref={reactFlowWrapper}>
<ReactFlow
@@ -307,4 +312,4 @@ const AgentFlow = () => {
);
};
export default AgentFlow;
export default AgentFlow;
-5
View File
@@ -1,5 +0,0 @@
import { createRoot } from 'react-dom/client'
import App from './App.tsx'
import './index.css'
createRoot(document.getElementById("root")!).render(<App />);
-1
View File
@@ -1 +0,0 @@
/// <reference types="vite/client" />
+3 -4
View File
@@ -3,10 +3,9 @@ import type { Config } from "tailwindcss";
export default {
darkMode: ["class"],
content: [
"./pages/**/*.{ts,tsx}",
"./components/**/*.{ts,tsx}",
"./app/**/*.{ts,tsx}",
"./src/**/*.{ts,tsx}",
'./components/**/*.{ts,tsx}',
'./app/**/*.{ts,tsx}',
'./src/**/*.{ts,tsx}',
],
prefix: "",
theme: {
-30
View File
@@ -1,30 +0,0 @@
{
"compilerOptions": {
"target": "ES2020",
"useDefineForClassFields": true,
"lib": ["ES2020", "DOM", "DOM.Iterable"],
"module": "ESNext",
"skipLibCheck": true,
/* Bundler mode */
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"isolatedModules": true,
"moduleDetection": "force",
"noEmit": true,
"jsx": "react-jsx",
/* Linting */
"strict": false,
"noUnusedLocals": false,
"noUnusedParameters": false,
"noImplicitAny": false,
"noFallthroughCasesInSwitch": false,
"baseUrl": ".",
"paths": {
"@/*": ["./src/*"]
}
},
"include": ["src"]
}
+22 -14
View File
@@ -1,19 +1,27 @@
{
"files": [],
"references": [
{ "path": "./tsconfig.app.json" },
{ "path": "./tsconfig.node.json" }
],
"compilerOptions": {
"baseUrl": ".",
"target": "es5",
"lib": ["dom", "dom.iterable", "esnext"],
"allowJs": true,
"skipLibCheck": true,
"strict": true,
"noEmit": true,
"esModuleInterop": true,
"module": "esnext",
"moduleResolution": "bundler",
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "preserve",
"incremental": true,
"plugins": [
{
"name": "next"
}
],
"paths": {
"@/*": ["./src/*"]
},
"noImplicitAny": false,
"noUnusedParameters": false,
"skipLibCheck": true,
"allowJs": true,
"noUnusedLocals": false,
"strictNullChecks": false
}
}
},
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
"exclude": ["node_modules"]
}
-22
View File
@@ -1,22 +0,0 @@
{
"compilerOptions": {
"target": "ES2022",
"lib": ["ES2023"],
"module": "ESNext",
"skipLibCheck": true,
/* Bundler mode */
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"isolatedModules": true,
"moduleDetection": "force",
"noEmit": true,
/* Linting */
"strict": true,
"noUnusedLocals": false,
"noUnusedParameters": false,
"noFallthroughCasesInSwitch": true
},
"include": ["vite.config.ts"]
}
-30
View File
@@ -1,30 +0,0 @@
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react-swc";
import path from "path";
import { componentTagger } from "lovable-tagger";
// https://vitejs.dev/config/
export default defineConfig(({ mode }) => ({
server: {
host: "::",
port: 8080,
proxy: {
'/api/llamacloud': {
target: 'https://api.cloud.llamaindex.ai',
changeOrigin: true,
rewrite: (path) => path.replace(/^\/api\/llamacloud/, ''),
secure: true,
},
},
},
plugins: [
react(),
mode === 'development' &&
componentTagger(),
].filter(Boolean),
resolve: {
alias: {
"@": path.resolve(__dirname, "./src"),
},
},
}));