feat: enhance project structure with server and workflow management

- Introduced a new server package with Fastify for handling API requests and workflows.
- Implemented user authentication and authorization with JWT and cookie management.
- Added endpoints for managing workflows, runs, and user accounts.
- Established a dashboard for monitoring workflow status and statistics.
- Included a script sandbox for executing user-defined scripts securely.
- Updated README with setup instructions and API documentation.
- Configured database migrations for user management.
- Enhanced logging capabilities for better traceability.
This commit is contained in:
2026-08-14 14:25:37 +07:00
parent 5574d6f723
commit 023cf83cfa
48 changed files with 6127 additions and 359 deletions
+64
View File
@@ -0,0 +1,64 @@
import { useState } from "react";
import { LuLogIn, LuUserPlus } from "react-icons/lu";
import { errorMessage } from "../api/client.js";
import { useLogin, useRegister } from "../api/hooks.js";
export function AuthPage({ needsSetup }) {
const login = useLogin();
const register = useRegister();
const [username, setUsername] = useState("");
const [password, setPassword] = useState("");
const mutation = needsSetup ? register : login;
const error = mutation.isError ? errorMessage(mutation.error) : null;
function onSubmit(e) {
e.preventDefault();
mutation.mutate({ username, password });
}
return (
<div className="min-h-screen flex items-center justify-center p-4 bg-base-200">
<form
onSubmit={onSubmit}
className="fieldset bg-base-100 border-base-300 rounded-box w-full max-w-sm border p-6 gap-3"
>
<legend className="fieldset-legend text-lg">
{needsSetup ? "Create admin" : "Sign in"}
</legend>
<label className="label" htmlFor="username">
Username
</label>
<input
id="username"
className="input w-full"
autoComplete="username"
value={username}
onChange={(e) => setUsername(e.target.value)}
required
/>
<label className="label" htmlFor="password">
Password
</label>
<input
id="password"
type="password"
className="input w-full"
autoComplete={needsSetup ? "new-password" : "current-password"}
value={password}
onChange={(e) => setPassword(e.target.value)}
required
minLength={8}
/>
{error ? <p className="text-error text-sm">{error}</p> : null}
<button
type="submit"
className="btn btn-primary mt-2"
disabled={mutation.isPending}
>
{needsSetup ? <LuUserPlus className="size-4" /> : <LuLogIn className="size-4" />}
{needsSetup ? "Create" : "Sign in"}
</button>
</form>
</div>
);
}