Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .env-example
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
HATCH_ENV=development
5 changes: 4 additions & 1 deletion .husky/pre-commit
Original file line number Diff line number Diff line change
@@ -1 +1,4 @@
bun test
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"

bun run format
Binary file modified bun.lockb
Binary file not shown.
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,18 @@
"packages/*"
],
"scripts": {
"prepare": "husky",
"start:frontend": "bun run --cwd packages/frontend dev",
"build:frontend": "bun run --cwd packages/frontend build",
"lint:frontend": "bun run --cwd packages/frontend lint",
"preview:frontend": "bun run --cwd packages/frontend preview",
"prepare": "husky",
"format": "bun run format:frontend && bun run format:api",
"format:frontend": "prettier --write 'packages/frontend/**/*.{js,ts,tsx,json,md,scss,css}'",
"format:api": "prettier --write 'packages/api/**/*.{js,ts,tsx,json,md,scss,css}'"
},
"devDependencies": {
"prettier": "3.5.1"
"husky": "^9.1.7",
"prettier": "3.5.3"
},
"packageManager": "bun@latest"
}
2 changes: 2 additions & 0 deletions packages/frontend/.env-example
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
VITE_API_BASE_URL=http://127.0.0.1:8000
NODE_ENV=development
8 changes: 7 additions & 1 deletion packages/frontend/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,10 @@ dist-ssr
*.njsproj
*.sln
*.sw?
/stats.html
/stats.html


.env
.env.local

.vscode
1 change: 0 additions & 1 deletion packages/frontend/.husky/pre-commit

This file was deleted.

74 changes: 39 additions & 35 deletions packages/frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,20 @@
"prepare": "husky"
},
"dependencies": {
"@mantine/carousel": "^7.17.0",
"@mantine/charts": "^7.17.0",
"@mantine/code-highlight": "^7.17.0",
"@mantine/core": "^7.17.0",
"@mantine/dates": "^7.17.0",
"@mantine/dropzone": "^7.17.0",
"@mantine/form": "^7.17.0",
"@mantine/hooks": "^7.17.0",
"@mantine/modals": "^7.17.0",
"@mantine/notifications": "^7.17.0",
"@mantine/nprogress": "^7.17.0",
"@mantine/spotlight": "^7.17.0",
"@mantine/tiptap": "^7.17.0",
"@headlessui/react": "^2.2.0",
"@mantine/carousel": "^7.17.1",
"@mantine/charts": "^7.17.1",
"@mantine/code-highlight": "^7.17.1",
"@mantine/core": "^7.17.1",
"@mantine/dates": "^7.17.1",
"@mantine/dropzone": "^7.17.1",
"@mantine/form": "^7.17.1",
"@mantine/hooks": "^7.17.1",
"@mantine/modals": "^7.17.1",
"@mantine/notifications": "^7.17.1",
"@mantine/nprogress": "^7.17.1",
"@mantine/spotlight": "^7.17.1",
"@mantine/tiptap": "^7.17.1",
"@pywebflow/api": "workspace:*",
"@radix-ui/react-dialog": "^1.1.6",
"@radix-ui/react-navigation-menu": "^1.2.5",
Expand All @@ -37,55 +38,58 @@
"@radix-ui/react-slot": "^1.1.2",
"@radix-ui/react-toast": "^1.2.6",
"@radix-ui/react-tooltip": "^1.1.8",
"@radix-ui/themes": "^3.2.0",
"@tabler/icons-react": "^3.30.0",
"@tailwindcss/postcss": "^4.0.7",
"@tailwindcss/vite": "^4.0.7",
"@radix-ui/themes": "^3.2.1",
"@tabler/icons-react": "^3.31.0",
"@tailwindcss/postcss": "^4.0.12",
"@tailwindcss/vite": "^4.0.12",
"@tiptap/extension-link": "^2.11.5",
"@tiptap/pm": "^2.11.5",
"@tiptap/react": "^2.11.5",
"@tiptap/starter-kit": "^2.11.5",
"@xyflow/react": "^12.4.3",
"@xyflow/react": "^12.4.4",
"autoprefixer": "^10.4.20",
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
"dayjs": "^1.11.13",
"dompurify": "^3.2.4",
"embla-carousel-react": "^8.5.2",
"framer-motion": "^12.4.7",
"lucide-react": "^0.475.0",
"framer-motion": "^12.4.10",
"html-react-parser": "^5.2.2",
"lucide-react": "^0.477.0",
"next-themes": "^0.4.4",
"postcss": "^8.5.3",
"react": "^19.0.0",
"react-dom": "^19.0.0",
"react-helmet-async": "^2.0.5",
"react-icons": "^5.5.0",
"react-remark": "^2.1.0",
"react-router-dom": "^7.2.0",
"react-router-dom": "^7.3.0",
"recharts": "^2.15.1",
"sass": "^1.85.0",
"tailwind-merge": "^3.0.1",
"tailwindcss": "^4.0.7",
"tailwindcss-animate": "^1.0.7"
"sass": "^1.85.1",
"tailwind-merge": "^3.0.2",
"tailwindcss": "^4.0.12",
"tailwindcss-animate": "^1.0.7",
"zustand": "^5.0.3"
},
"license": "apache-2.0",
"devDependencies": {
"eslint-config-prettier": "^10.0.1",
"eslint-plugin-prettier": "^5.2.3",
"@types/node": "^22.13.4",
"@types/node": "^22.13.9",
"@types/react": "^19.0.10",
"@types/react-dom": "^19.0.4",
"@typescript-eslint/eslint-plugin": "^8.24.1",
"@typescript-eslint/parser": "^8.24.1",
"@typescript-eslint/eslint-plugin": "^8.26.0",
"@typescript-eslint/parser": "^8.26.0",
"@vitejs/plugin-react": "^4.3.4",
"eslint": "^9.20.1",
"eslint-plugin-react-hooks": "^5.1.0",
"@vitejs/plugin-react-swc": "^3.8.0",
"eslint": "^9.21.0",
"eslint-config-prettier": "^10.1.1",
"eslint-plugin-prettier": "^5.2.3",
"eslint-plugin-react-hooks": "^5.2.0",
"eslint-plugin-react-refresh": "^0.4.19",
"husky": "^9.1.7",
"postcss-preset-mantine": "^1.17.0",
"postcss-simple-vars": "^7.0.1",
"rollup-plugin-visualizer": "^5.14.0",
"typescript": "^5.7.3",
"vite": "^6.1.1"
"typescript": "^5.8.2",
"vite": "^6.2.1"
},
"keywords": [
"pywebflow",
Expand Down
59 changes: 8 additions & 51 deletions packages/frontend/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,55 +1,12 @@
import { useEffect, useState } from 'react';
import ControlsComp from './components/Controls.tsx';
import MinimapComp from './components/Minimap.tsx';
import Status from './components/Status.tsx';
import { SidebarProvider, SidebarTrigger } from './components/ui/sidebar.tsx';
import AppSidebar from './components/App-Sidebar.tsx';
import BackgroundWrapper from './components/BackgroundWrapper.tsx';
import InjectedHtml from './components/InjectedHtml.tsx';
import {
getSidebarItems,
SidebarResponse,
} from '@pywebflow/api/src/sidebar.ts';

export function App() {
const [sidebarItems, setSidebarItems] = useState<SidebarResponse['items']>(
[],
);
const [sidebarVisible, setSidebarVisible] = useState<boolean>(false);
const [sidebarLabel, setSidebarLabel] = useState<string>('');
const [defaultOpen, setDefaultOpen] = useState<boolean>(false);

useEffect(() => {
const fetchSidebarItems = async () => {
const response: SidebarResponse = await getSidebarItems();
setSidebarItems(response.items);
setSidebarVisible(response.visible);
setSidebarLabel(response.label);
setDefaultOpen(response.default_open);
};

fetchSidebarItems();
}, []);
import { Suspense } from 'react';
import { RouterProvider } from 'react-router-dom';
import router from './routes.tsx';
import { LoadingPage } from './components/loader.tsx';

export default function App() {
return (
<div className="App h-screen overflow-hidden">
<SidebarProvider defaultOpen={defaultOpen}>
<div className="flex h-full">
{sidebarVisible && (
<AppSidebar items={sidebarItems} label={sidebarLabel} />
)}
{sidebarVisible && <SidebarTrigger />}
<div className="flex-1 overflow-auto">
<Status />
<ControlsComp />
<MinimapComp />
<BackgroundWrapper />
<InjectedHtml /> {/* Add the InjectedHtml component here */}
</div>
</div>
</SidebarProvider>
</div>
<Suspense fallback={<LoadingPage />}>
<RouterProvider router={router} />
</Suspense>
);
}

export default App;
71 changes: 71 additions & 0 deletions packages/frontend/src/Flow.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import { useEffect, useState } from 'react';
import ControlsComp from './components/Controls.tsx';
import MinimapComp from './components/Minimap.tsx';
import Status from './components/Status.tsx';
import { SidebarProvider, SidebarTrigger } from './components/ui/sidebar.tsx';
import AppSidebar from './components/App-Sidebar.tsx';
import BackgroundWrapper from './components/BackgroundWrapper.tsx';
import InjectedHtml from './components/InjectedHtml.tsx';
import {
getSidebarItems,
SidebarResponse,
} from '@pywebflow/api/src/sidebar.ts';

export function App() {
const [sidebarItems, setSidebarItems] = useState<SidebarResponse['items']>(
[],
);
const [sidebarVisible, setSidebarVisible] = useState<boolean>(false);
const [sidebarLabel, setSidebarLabel] = useState<string>('');
const [defaultOpen, setDefaultOpen] = useState<boolean>(false);
const [loading, setLoading] = useState<boolean>(true);
const [error, setError] = useState<string | null>(null);

useEffect(() => {
const fetchSidebarItems = async () => {
try {
setLoading(true);
setError(null);

const response: SidebarResponse = await getSidebarItems();
setSidebarItems(response.items);
setSidebarVisible(response.visible);
setSidebarLabel(response.label);
setDefaultOpen(response.default_open);
} catch (err) {
console.error('Error fetching sidebar items:', err);
setError('Failed to load sidebar');
} finally {
setLoading(false);
}
};

fetchSidebarItems();
}, []);

return (
<div className="App h-screen overflow-hidden">
<SidebarProvider defaultOpen={defaultOpen}>
<div className="flex h-full">
{loading && <p className="p-4 text-gray-500">Loading sidebar...</p>}
{error && <p className="p-4 text-red-500">{error}</p>}

{!loading && !error && sidebarVisible && (
<AppSidebar items={sidebarItems} label={sidebarLabel} />
)}
{!loading && !error && sidebarVisible && <SidebarTrigger />}

<div className="flex-1 overflow-auto">
<Status />
<ControlsComp />
<MinimapComp />
<BackgroundWrapper />
<InjectedHtml />
</div>
</div>
</SidebarProvider>
</div>
);
}

export default App;
12 changes: 9 additions & 3 deletions packages/frontend/src/Layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,18 @@ export default function Layout() {
const loadInitialConfig = async () => {
try {
const fetchedConfig = await getConfig();
if (fetchedConfig[0].colorMode) {
setTheme(fetchedConfig[0].colorMode);

if (Array.isArray(fetchedConfig) && fetchedConfig.length > 0) {
if (fetchedConfig[0]?.colorMode) {
setTheme(fetchedConfig[0].colorMode);
}
setConfig(fetchedConfig[0]);
} else {
setConfig({});
}
setConfig(fetchedConfig[0]);
} catch (error) {
console.error('Error fetching initial config:', error);
setConfig({}); // Fallback to empty object on error
}
};

Expand Down
18 changes: 18 additions & 0 deletions packages/frontend/src/NotFound.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { Link } from 'react-router-dom';

export default function NotFound() {
return (
<div className="flex flex-col items-center justify-center h-screen text-center">
<h1 className="text-4xl font-bold text-red-600">404</h1>
<p className="text-lg text-gray-600">
Oops! The page you're looking for doesn't exist.
</p>
<Link
to="/"
className="mt-4 px-4 py-2 bg-blue-500 text-white rounded-lg hover:bg-blue-600"
>
Go Home
</Link>
</div>
);
}
Loading