botschat 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +201 -0
- package/README.md +213 -0
- package/migrations/0001_initial.sql +88 -0
- package/migrations/0002_rename_projects_to_channels.sql +53 -0
- package/migrations/0003_messages.sql +14 -0
- package/migrations/0004_jobs.sql +15 -0
- package/migrations/0005_deleted_cron_jobs.sql +6 -0
- package/migrations/0006_tasks_add_model.sql +2 -0
- package/migrations/0007_sessions.sql +25 -0
- package/migrations/0008_remove_openclaw_fields.sql +8 -0
- package/package.json +53 -0
- package/packages/api/package.json +17 -0
- package/packages/api/src/do/connection-do.ts +929 -0
- package/packages/api/src/env.ts +8 -0
- package/packages/api/src/index.ts +297 -0
- package/packages/api/src/routes/agents.ts +68 -0
- package/packages/api/src/routes/auth.ts +105 -0
- package/packages/api/src/routes/channels.ts +185 -0
- package/packages/api/src/routes/jobs.ts +65 -0
- package/packages/api/src/routes/models.ts +22 -0
- package/packages/api/src/routes/pairing.ts +76 -0
- package/packages/api/src/routes/projects.ts +177 -0
- package/packages/api/src/routes/sessions.ts +171 -0
- package/packages/api/src/routes/tasks.ts +375 -0
- package/packages/api/src/routes/upload.ts +52 -0
- package/packages/api/src/utils/auth.ts +101 -0
- package/packages/api/src/utils/id.ts +19 -0
- package/packages/api/tsconfig.json +18 -0
- package/packages/plugin/dist/index.d.ts +19 -0
- package/packages/plugin/dist/index.d.ts.map +1 -0
- package/packages/plugin/dist/index.js +17 -0
- package/packages/plugin/dist/index.js.map +1 -0
- package/packages/plugin/dist/src/accounts.d.ts +12 -0
- package/packages/plugin/dist/src/accounts.d.ts.map +1 -0
- package/packages/plugin/dist/src/accounts.js +103 -0
- package/packages/plugin/dist/src/accounts.js.map +1 -0
- package/packages/plugin/dist/src/channel.d.ts +206 -0
- package/packages/plugin/dist/src/channel.d.ts.map +1 -0
- package/packages/plugin/dist/src/channel.js +1248 -0
- package/packages/plugin/dist/src/channel.js.map +1 -0
- package/packages/plugin/dist/src/runtime.d.ts +3 -0
- package/packages/plugin/dist/src/runtime.d.ts.map +1 -0
- package/packages/plugin/dist/src/runtime.js +18 -0
- package/packages/plugin/dist/src/runtime.js.map +1 -0
- package/packages/plugin/dist/src/types.d.ts +179 -0
- package/packages/plugin/dist/src/types.d.ts.map +1 -0
- package/packages/plugin/dist/src/types.js +6 -0
- package/packages/plugin/dist/src/types.js.map +1 -0
- package/packages/plugin/dist/src/ws-client.d.ts +51 -0
- package/packages/plugin/dist/src/ws-client.d.ts.map +1 -0
- package/packages/plugin/dist/src/ws-client.js +170 -0
- package/packages/plugin/dist/src/ws-client.js.map +1 -0
- package/packages/plugin/openclaw.plugin.json +11 -0
- package/packages/plugin/package.json +39 -0
- package/packages/plugin/tsconfig.json +20 -0
- package/packages/web/dist/assets/index-C-wI8eHy.css +1 -0
- package/packages/web/dist/assets/index-CbPEKHLG.js +93 -0
- package/packages/web/dist/index.html +17 -0
- package/packages/web/index.html +16 -0
- package/packages/web/package.json +29 -0
- package/packages/web/postcss.config.js +6 -0
- package/packages/web/src/App.tsx +827 -0
- package/packages/web/src/api.ts +242 -0
- package/packages/web/src/components/ChatWindow.tsx +864 -0
- package/packages/web/src/components/CronDetail.tsx +943 -0
- package/packages/web/src/components/CronSidebar.tsx +123 -0
- package/packages/web/src/components/DebugLogPanel.tsx +258 -0
- package/packages/web/src/components/IconRail.tsx +163 -0
- package/packages/web/src/components/JobList.tsx +120 -0
- package/packages/web/src/components/LoginPage.tsx +178 -0
- package/packages/web/src/components/MessageContent.tsx +1082 -0
- package/packages/web/src/components/ModelSelect.tsx +87 -0
- package/packages/web/src/components/ScheduleEditor.tsx +403 -0
- package/packages/web/src/components/SessionTabs.tsx +246 -0
- package/packages/web/src/components/Sidebar.tsx +331 -0
- package/packages/web/src/components/TaskBar.tsx +413 -0
- package/packages/web/src/components/ThreadPanel.tsx +212 -0
- package/packages/web/src/debug-log.ts +58 -0
- package/packages/web/src/index.css +170 -0
- package/packages/web/src/main.tsx +10 -0
- package/packages/web/src/store.ts +492 -0
- package/packages/web/src/ws.ts +99 -0
- package/packages/web/tailwind.config.js +65 -0
- package/packages/web/tsconfig.json +18 -0
- package/packages/web/vite.config.ts +20 -0
- package/scripts/dev.sh +122 -0
- package/tsconfig.json +18 -0
- package/wrangler.toml +40 -0
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
import React, { useState } from "react";
|
|
2
|
+
import { authApi, setToken } from "../api";
|
|
3
|
+
import { useAppDispatch } from "../store";
|
|
4
|
+
import { dlog } from "../debug-log";
|
|
5
|
+
|
|
6
|
+
export function LoginPage() {
|
|
7
|
+
const dispatch = useAppDispatch();
|
|
8
|
+
const [isRegister, setIsRegister] = useState(false);
|
|
9
|
+
const [email, setEmail] = useState("");
|
|
10
|
+
const [password, setPassword] = useState("");
|
|
11
|
+
const [displayName, setDisplayName] = useState("");
|
|
12
|
+
const [error, setError] = useState("");
|
|
13
|
+
const [loading, setLoading] = useState(false);
|
|
14
|
+
|
|
15
|
+
const handleSubmit = async (e: React.FormEvent) => {
|
|
16
|
+
e.preventDefault();
|
|
17
|
+
setError("");
|
|
18
|
+
setLoading(true);
|
|
19
|
+
|
|
20
|
+
try {
|
|
21
|
+
let res;
|
|
22
|
+
if (isRegister) {
|
|
23
|
+
dlog.info("Auth", `Registering new account: ${email}`);
|
|
24
|
+
res = await authApi.register(email, password, displayName || undefined);
|
|
25
|
+
} else {
|
|
26
|
+
dlog.info("Auth", `Logging in: ${email}`);
|
|
27
|
+
res = await authApi.login(email, password);
|
|
28
|
+
}
|
|
29
|
+
dlog.info("Auth", `${isRegister ? "Register" : "Login"} success — user ${res.id} (${res.email})`);
|
|
30
|
+
setToken(res.token);
|
|
31
|
+
dispatch({
|
|
32
|
+
type: "SET_USER",
|
|
33
|
+
user: { id: res.id, email: res.email, displayName: res.displayName },
|
|
34
|
+
});
|
|
35
|
+
} catch (err) {
|
|
36
|
+
const message = err instanceof Error ? err.message : "Something went wrong";
|
|
37
|
+
dlog.error("Auth", `${isRegister ? "Register" : "Login"} failed: ${message}`);
|
|
38
|
+
setError(message);
|
|
39
|
+
} finally {
|
|
40
|
+
setLoading(false);
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
return (
|
|
45
|
+
<div
|
|
46
|
+
className="min-h-screen flex items-center justify-center"
|
|
47
|
+
style={{ background: "var(--bg-secondary)" }}
|
|
48
|
+
>
|
|
49
|
+
<div className="w-full max-w-md">
|
|
50
|
+
{/* Header */}
|
|
51
|
+
<div className="text-center mb-8">
|
|
52
|
+
<div
|
|
53
|
+
className="inline-flex items-center justify-center w-16 h-16 rounded-xl text-white text-2xl font-bold mb-4"
|
|
54
|
+
style={{ background: "#1264A3" }}
|
|
55
|
+
>
|
|
56
|
+
BC
|
|
57
|
+
</div>
|
|
58
|
+
<h1 className="text-3xl font-bold" style={{ color: "var(--text-primary)" }}>
|
|
59
|
+
BotsChat
|
|
60
|
+
</h1>
|
|
61
|
+
<p className="mt-2" style={{ color: "var(--text-secondary)" }}>
|
|
62
|
+
Multi-channel AI chat powered by OpenClaw
|
|
63
|
+
</p>
|
|
64
|
+
</div>
|
|
65
|
+
|
|
66
|
+
{/* Form card */}
|
|
67
|
+
<div
|
|
68
|
+
className="rounded-md p-8"
|
|
69
|
+
style={{
|
|
70
|
+
background: "var(--bg-surface)",
|
|
71
|
+
boxShadow: "var(--shadow-lg)",
|
|
72
|
+
}}
|
|
73
|
+
>
|
|
74
|
+
<h2 className="text-h1 mb-6" style={{ color: "var(--text-primary)" }}>
|
|
75
|
+
{isRegister ? "Create account" : "Sign in"}
|
|
76
|
+
</h2>
|
|
77
|
+
|
|
78
|
+
<form onSubmit={handleSubmit} className="space-y-4">
|
|
79
|
+
{isRegister && (
|
|
80
|
+
<div>
|
|
81
|
+
<label className="block text-caption font-bold mb-1" style={{ color: "var(--text-secondary)" }}>
|
|
82
|
+
Display Name
|
|
83
|
+
</label>
|
|
84
|
+
<input
|
|
85
|
+
type="text"
|
|
86
|
+
value={displayName}
|
|
87
|
+
onChange={(e) => setDisplayName(e.target.value)}
|
|
88
|
+
className="w-full px-3 py-2.5 text-body rounded-sm focus:outline-none placeholder:text-[--text-muted]"
|
|
89
|
+
style={{
|
|
90
|
+
background: "var(--bg-surface)",
|
|
91
|
+
color: "var(--text-primary)",
|
|
92
|
+
border: "1px solid var(--border)",
|
|
93
|
+
}}
|
|
94
|
+
placeholder="Your name"
|
|
95
|
+
/>
|
|
96
|
+
</div>
|
|
97
|
+
)}
|
|
98
|
+
|
|
99
|
+
<div>
|
|
100
|
+
<label className="block text-caption font-bold mb-1" style={{ color: "var(--text-secondary)" }}>
|
|
101
|
+
Email
|
|
102
|
+
</label>
|
|
103
|
+
<input
|
|
104
|
+
type="email"
|
|
105
|
+
value={email}
|
|
106
|
+
onChange={(e) => setEmail(e.target.value)}
|
|
107
|
+
required
|
|
108
|
+
className="w-full px-3 py-2.5 text-body rounded-sm focus:outline-none placeholder:text-[--text-muted]"
|
|
109
|
+
style={{
|
|
110
|
+
background: "var(--bg-surface)",
|
|
111
|
+
color: "var(--text-primary)",
|
|
112
|
+
border: "1px solid var(--border)",
|
|
113
|
+
}}
|
|
114
|
+
placeholder="you@example.com"
|
|
115
|
+
/>
|
|
116
|
+
</div>
|
|
117
|
+
|
|
118
|
+
<div>
|
|
119
|
+
<label className="block text-caption font-bold mb-1" style={{ color: "var(--text-secondary)" }}>
|
|
120
|
+
Password
|
|
121
|
+
</label>
|
|
122
|
+
<input
|
|
123
|
+
type="password"
|
|
124
|
+
value={password}
|
|
125
|
+
onChange={(e) => setPassword(e.target.value)}
|
|
126
|
+
required
|
|
127
|
+
className="w-full px-3 py-2.5 text-body rounded-sm focus:outline-none placeholder:text-[--text-muted]"
|
|
128
|
+
style={{
|
|
129
|
+
background: "var(--bg-surface)",
|
|
130
|
+
color: "var(--text-primary)",
|
|
131
|
+
border: "1px solid var(--border)",
|
|
132
|
+
}}
|
|
133
|
+
placeholder="Enter password"
|
|
134
|
+
/>
|
|
135
|
+
</div>
|
|
136
|
+
|
|
137
|
+
{error && (
|
|
138
|
+
<div
|
|
139
|
+
className="text-caption px-3 py-2 rounded-sm"
|
|
140
|
+
style={{ background: "rgba(224,30,90,0.1)", color: "var(--accent-red)" }}
|
|
141
|
+
>
|
|
142
|
+
{error}
|
|
143
|
+
</div>
|
|
144
|
+
)}
|
|
145
|
+
|
|
146
|
+
<button
|
|
147
|
+
type="submit"
|
|
148
|
+
disabled={loading}
|
|
149
|
+
className="w-full py-2.5 font-bold text-body text-white rounded-sm disabled:opacity-50 transition-colors hover:brightness-110"
|
|
150
|
+
style={{ background: "var(--bg-active)" }}
|
|
151
|
+
>
|
|
152
|
+
{loading
|
|
153
|
+
? "..."
|
|
154
|
+
: isRegister
|
|
155
|
+
? "Create account"
|
|
156
|
+
: "Sign in"}
|
|
157
|
+
</button>
|
|
158
|
+
</form>
|
|
159
|
+
|
|
160
|
+
<div className="mt-6 text-center">
|
|
161
|
+
<button
|
|
162
|
+
onClick={() => {
|
|
163
|
+
setIsRegister(!isRegister);
|
|
164
|
+
setError("");
|
|
165
|
+
}}
|
|
166
|
+
className="text-caption hover:underline"
|
|
167
|
+
style={{ color: "var(--text-link)" }}
|
|
168
|
+
>
|
|
169
|
+
{isRegister
|
|
170
|
+
? "Already have an account? Sign in"
|
|
171
|
+
: "Don't have an account? Register"}
|
|
172
|
+
</button>
|
|
173
|
+
</div>
|
|
174
|
+
</div>
|
|
175
|
+
</div>
|
|
176
|
+
</div>
|
|
177
|
+
);
|
|
178
|
+
}
|