tangled
alpha
login
or
join now
futur.blue
/
pegasus
57
fork
atom
objective categorical abstract machine language personal data server
57
fork
atom
overview
issues
2
pulls
pipelines
Fix account switcher, admin pages sizing
futur.blue
2 months ago
f0e70709
51cda44f
verified
This commit was signed with the committer's
known signature
.
futur.blue
SSH Key Fingerprint:
SHA256:QHGqHWNpqYyw9bt8KmPuJIyeZX9SZewBZ0PR1COtKQ0=
+40
-32
4 changed files
expand all
collapse all
unified
split
frontend
src
components
AccountSwitcher.mlx
Sidebar.mlx
templates
AdminInvitesPage.mlx
AdminUsersPage.mlx
+8
-4
frontend/src/components/AccountSwitcher.mlx
···
10
10
active:bg-mist-20/40"
11
11
12
12
let button_class_default =
13
13
-
"group min-w-48 flex flex-row items-center gap-x-1 px-2 py-1.5 -mx-2 \
13
13
+
"group w-64 flex flex-row items-center gap-x-1 px-2 py-1.5 -mx-2 \
14
14
rounded-lg focus-visible:outline-none hover:bg-mist-20/40 \
15
15
active:bg-mist-20/40"
16
16
···
44
44
[%browser_only
45
45
fun newDid ->
46
46
if newDid <> current_user.did then
47
47
-
let formData = Fetch.FormData.make () in
48
48
-
Fetch.FormData.set "did" newDid formData ;
47
47
+
let body =
48
48
+
Fetch.BodyInit.make
49
49
+
(Webapi.Url.URLSearchParams.makeWithArray [|("did", newDid)|]
50
50
+
|> Webapi.Url.URLSearchParams.toString )
51
51
+
in
49
52
let _ =
50
53
Fetch.fetchWithInit "/account/switch"
51
54
(Fetch.RequestInit.make ~method_:Fetch.Post
52
52
-
~body:(Fetch.BodyInit.makeWithFormData formData)
55
55
+
~headers:(Fetch.HeadersInit.makeWithArray [|("Content-Type", "application/x-www-form-urlencoded")|])
56
56
+
~body
53
57
() )
54
58
|> Js.Promise.then_ (fun response ->
55
59
if Fetch.Response.ok response then (
+1
-1
frontend/src/components/Sidebar.mlx
···
5
5
let[@react.component] make ~pages ~active_page ?header () =
6
6
let selected_class = "text-mana-100 font-medium" in
7
7
let unselected_class = "text-mist-100 hover:text-mana-100" in
8
8
-
<aside className="flex flex-col gap-y-2 min-w-24 max-w-3xs">
8
8
+
<aside className="flex flex-col gap-y-2 w-auto min-w-32">
9
9
(match header with Some h -> h | None -> null)
10
10
<nav className="flex flex-col gap-y-1 mt-2">
11
11
( List.map
+12
-10
frontend/src/templates/AdminInvitesPage.mlx
···
38
38
let editRemaining, setEditRemaining = useState (fun () -> "") in
39
39
(* delete confirmation state *)
40
40
let deleteConfirmFor, setDeleteConfirmFor = useState (fun () -> (None : invite option)) in
41
41
-
<div className="w-full max-w-3xl h-full px-4 sm:px-0 pt-16 mx-auto flex flex-col md:flex-row gap-12">
41
41
+
<div className="w-auto h-full max-w-full px-4 pt-16 mx-auto flex flex-1 flex-col md:flex-row justify-center gap-12">
42
42
<Sidebar pages=admin_pages active_page="/admin/invites" />
43
43
<main className="flex-1 w-full max-w-2xl">
44
44
<h1 className="text-2xl font-serif text-mana-200 mb-1">
···
138
138
</div>
139
139
| None -> null )
140
140
<div className="overflow-x-auto">
141
141
-
<table className="w-full min-w-xl text-sm">
142
142
-
<thead>
143
143
-
<tr className="text-left text-mist-80">
144
144
-
<th className="pb-2 font-normal">(string "Code")</th>
145
145
-
<th className="pb-2 font-normal">(string "For")</th>
146
146
-
<th className="pb-2 font-normal">(string "Remaining")</th>
147
147
-
<th className="pb-2 font-normal w-20"></th>
141
141
+
<table
142
142
+
className="w-full grid border-collapse text-sm"
143
143
+
style=(ReactDOM.Style.make ~gridTemplateColumns:"minmax(6rem, 1fr) 1fr minmax(2rem, 1fr) 4rem" ())>
144
144
+
<thead className="contents">
145
145
+
<tr className="contents text-left text-mist-80">
146
146
+
<th className="border-b border-mist-60/50 pb-2 font-normal">(string "Code")</th>
147
147
+
<th className="border-b border-mist-60/50 pb-2 font-normal">(string "For")</th>
148
148
+
<th className="border-b border-mist-60/50 pb-2 font-normal">(string "Remaining")</th>
149
149
+
<th className="border-b border-mist-60/50 pb-2 font-normal w-20"></th>
148
150
</tr>
149
151
</thead>
150
150
-
<tbody>
152
152
+
<tbody className="contents">
151
153
( List.map
152
154
(fun (invite : invite) ->
153
153
-
<tr key=invite.code className="border-t border-mist-60/50">
155
155
+
<tr key=invite.code className="contents">
154
156
<td className="py-3 pr-4">
155
157
<span className="font-mono text-mana-100">
156
158
(string invite.code)
+19
-17
frontend/src/templates/AdminUsersPage.mlx
···
62
62
let editValue, setEditValue = useState (fun () -> "") in
63
63
(* delete confirmation state *)
64
64
let deleteConfirmFor, setDeleteConfirmFor = useState (fun () -> (None : actor option)) in
65
65
-
<div className="w-full max-w-3xl h-full px-4 sm:px-0 pt-16 mx-auto flex flex-col md:flex-row gap-12">
65
65
+
<div className="w-auto h-full max-w-full px-4 pt-16 mx-auto flex flex-col md:flex-row gap-12">
66
66
<Sidebar pages=admin_pages active_page="/admin/users" />
67
67
<main className="flex-1 w-full max-w-2xl">
68
68
<h1 className="text-2xl font-serif text-mana-200 mb-1">
···
169
169
</div>
170
170
| None -> null )
171
171
<div className="overflow-x-auto">
172
172
-
<table className="w-full min-w-xl text-sm">
173
173
-
<thead>
174
174
-
<tr className="text-left text-mist-80">
175
175
-
<th className="pb-2 font-normal">(string "Handle")</th>
176
176
-
<th className="pb-2 font-normal">(string "Email")</th>
177
177
-
<th className="pb-2 font-normal">(string "Created at")</th>
178
178
-
<th className="pb-2 font-normal w-8"></th>
172
172
+
<table
173
173
+
className="w-full min-w-xl grid border-collapse text-sm"
174
174
+
style=(ReactDOM.Style.make ~gridTemplateColumns:"minmax(200px, 2fr) minmax(160px, 2fr) minmax(160px, 1.5fr) 1.25rem" ())>
175
175
+
<thead className="contents">
176
176
+
<tr className="contents text-left text-mist-80">
177
177
+
<th className="border-b border-mist-60/50 pb-2 font-normal">(string "Handle")</th>
178
178
+
<th className="border-b border-mist-60/50 pb-2 font-normal">(string "Email")</th>
179
179
+
<th className="border-b border-mist-60/50 pb-2 font-normal">(string "Created at")</th>
180
180
+
<th className="border-b border-mist-60/50 pb-2 font-normal w-8"></th>
179
181
</tr>
180
182
</thead>
181
181
-
<tbody>
183
183
+
<tbody className="contents">
182
184
( List.map
183
185
(fun (actor : actor) ->
184
186
if filter <> ""
···
187
189
&& not (contains_str actor.email filter) then null else
188
190
let handleClasses = "font-medium truncate " ^
189
191
(if actor.deactivated then "text-phoenix-100" else "text-mana-100") in
190
190
-
<tr key=actor.did className="border-t border-mist-60/50">
192
192
+
<tr key=actor.did className="contents">
191
193
<td className="py-3 pr-4">
192
194
<div className="flex items-center gap-3">
193
193
-
<div className="max-w-54">
195
195
+
<div className="max-w-54 truncate">
194
196
<p className=handleClasses ?title=(if actor.deactivated then Some "Deactivated" else None)>
195
197
(string actor.handle)
196
198
</p>
···
202
204
</td>
203
205
<td className="py-3 pr-4">
204
206
<div className="flex items-center gap-1">
205
205
-
<span className="text-mist-100">(string actor.email)</span>
207
207
+
<span className="text-mist-100 truncate">(string actor.email)</span>
206
208
( if actor.email_confirmed then
207
207
-
<CheckmarkIcon className="w-4 h-4 text-mana-100" />
209
209
+
<CheckmarkIcon className="flex-shrink-0 w-4 h-4 text-mana-100" />
208
210
else
209
209
-
<XIcon className="w-4 h-4 text-phoenix-100" /> )
211
211
+
<XIcon className="flex-shrink-0 w-4 h-4 text-phoenix-100" /> )
210
212
</div>
211
213
</td>
212
212
-
<td className="py-3 pr-4 text-mist-100">
214
214
+
<td className="py-3 pr-4 text-mist-100 truncate">
213
215
(string actor.created_at)
214
216
</td>
215
217
<td className="py-3">
216
218
<ClientOnly fallback=(
217
217
-
<button className="p-1 text-mist-80 hover:text-mana-100">
219
219
+
<button className="text-mist-80 hover:text-mana-100">
218
220
<EllipsisIcon className="w-5 h-5" />
219
221
</button>
220
222
)>
···
228
230
setMenuOpenFor (fun _ -> if o then Some actor.did else None))>
229
231
<Aria.Pressable>
230
232
<button
231
231
-
className="p-1 text-mist-80 hover:text-mana-100 cursor-pointer"
233
233
+
className="text-mist-80 hover:text-mana-100 cursor-pointer"
232
234
onClick=(fun _ -> setMenuOpenFor (fun _ -> Some actor.did))>
233
235
<EllipsisIcon className="w-5 h-5" />
234
236
</button>