Skip to content

Commit a91c8d0

Browse files
refracto: using intl api
1 parent b366e25 commit a91c8d0

File tree

13 files changed

+310
-34
lines changed

13 files changed

+310
-34
lines changed

frontend/deno.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@
2727
"@std/front-matter": "jsr:@std/front-matter@1",
2828
"@std/semver": "jsr:@std/semver@1",
2929

30-
"@augustinmauroy/twas": "jsr:@augustinmauroy/twas@^1.0.0",
3130
"$imagescript": "https://deno.land/x/[email protected]/mod.ts",
3231

3332
"@deno/gfm": "jsr:@deno/[email protected]",

frontend/deno.lock

Lines changed: 1 addition & 10 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

frontend/islands/admin/ScopeEdit.tsx

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
// Copyright 2024 the JSR authors. All rights reserved. MIT license.
2+
import type { FullScope } from "../../utils/api_types.ts";
3+
import { useState } from "preact/hooks";
4+
import { timeAgo } from "../../utils/timeAgo.ts";
5+
import { api, path } from "../../utils/api.ts";
6+
import { TableData, TableRow } from "../../components/Table.tsx";
7+
8+
export default function AdminScopeEdit({ scope }: { scope: FullScope }) {
9+
const [edit, setEdit] = useState(false);
10+
const [processing, setProcessing] = useState(false);
11+
const [packageLimit, setPackageLimit] = useState(
12+
String(scope.quotas.packageLimit),
13+
);
14+
const [newPackagePerWeekLimit, setNewPackagePerWeekLimit] = useState(
15+
String(scope.quotas.newPackagePerWeekLimit),
16+
);
17+
const [publishAttemptsPerWeekLimit, setPublishAttemptsPerWeekLimit] =
18+
useState(
19+
String(scope.quotas.publishAttemptsPerWeekLimit),
20+
);
21+
22+
return (
23+
<TableRow key={scope.scope}>
24+
<TableData>
25+
<a href={`/@${scope.scope}`}>{scope.scope}</a>
26+
</TableData>
27+
<TableData title={scope.creator.id}>
28+
<a href={`/user/${scope.creator.id}`}>{scope.creator.name}</a>
29+
</TableData>
30+
<TableData>
31+
{edit
32+
? (
33+
<input
34+
type="number"
35+
class="block w-28 p-1.5 text-right input-container input"
36+
disabled={processing}
37+
value={packageLimit}
38+
onChange={(e) => setPackageLimit(e.currentTarget.value)}
39+
required
40+
/>
41+
)
42+
: packageLimit}
43+
</TableData>
44+
<TableData>
45+
{edit
46+
? (
47+
<input
48+
type="number"
49+
class="block w-28 p-1.5 text-right input-container input"
50+
disabled={processing}
51+
value={newPackagePerWeekLimit}
52+
onChange={(e) => setNewPackagePerWeekLimit(e.currentTarget.value)}
53+
required
54+
/>
55+
)
56+
: newPackagePerWeekLimit}
57+
</TableData>
58+
<TableData>
59+
{edit
60+
? (
61+
<input
62+
type="number"
63+
class="block w-28 p-1.5 text-right input-container input"
64+
disabled={processing}
65+
value={publishAttemptsPerWeekLimit}
66+
onChange={(e) =>
67+
setPublishAttemptsPerWeekLimit(e.currentTarget.value)}
68+
required
69+
/>
70+
)
71+
: publishAttemptsPerWeekLimit}
72+
</TableData>
73+
<TableData title={new Date(scope.createdAt).toISOString().slice(0, 10)}>
74+
{timeAgo(new Date(scope.createdAt))}
75+
</TableData>
76+
<TableData align="right">
77+
{edit
78+
? (
79+
<>
80+
<button
81+
type="button"
82+
disabled={processing}
83+
onClick={() => {
84+
setProcessing(true);
85+
api.patch(path`/admin/scopes/${scope.scope}`, {
86+
packageLimit: +packageLimit,
87+
newPackagePerWeekLimit: +newPackagePerWeekLimit,
88+
versionPublishPerWeekLimit: +publishAttemptsPerWeekLimit,
89+
}).then((res) => {
90+
setProcessing(false);
91+
if (res.ok) {
92+
setEdit(false);
93+
} else {
94+
console.error(res);
95+
}
96+
});
97+
}}
98+
class="link disabled:text-jsr-gray-500 disabled:hover:cursor-wait"
99+
>
100+
Save<span class="sr-only">, {scope.scope}</span>
101+
</button>
102+
<button
103+
type="button"
104+
onClick={() => {
105+
setEdit(false);
106+
setPackageLimit(String(scope.quotas.packageLimit));
107+
setNewPackagePerWeekLimit(
108+
String(scope.quotas.newPackagePerWeekLimit),
109+
);
110+
setPublishAttemptsPerWeekLimit(
111+
String(scope.quotas.publishAttemptsPerWeekLimit),
112+
);
113+
}}
114+
class="link ml-2"
115+
>
116+
Cancel<span class="sr-only">, {scope.scope}</span>
117+
</button>
118+
</>
119+
)
120+
: (
121+
<button
122+
type="button"
123+
onClick={() => setEdit(true)}
124+
class="link"
125+
>
126+
Edit<span class="sr-only">, {scope.scope}</span>
127+
</button>
128+
)}
129+
</TableData>
130+
</TableRow>
131+
);
132+
}

frontend/islands/admin/UserEdit.tsx

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
// Copyright 2024 the JSR authors. All rights reserved. MIT license.
2+
import { useState } from "preact/hooks";
3+
import { timeAgo } from "../../utils/timeAgo.ts";
4+
import { FullUser } from "../../utils/api_types.ts";
5+
import { api, path } from "../../utils/api.ts";
6+
import { TableData, TableRow } from "../../components/Table.tsx";
7+
8+
export default function UserEdit({ user }: { user: FullUser }) {
9+
const [edit, setEdit] = useState(false);
10+
const [processing, setProcessing] = useState(false);
11+
const [isStaff, setIsStaff] = useState(user.isStaff);
12+
const [isBlocked, setIsBlocked] = useState(user.isBlocked);
13+
const [scopeLimit, setScopeLimit] = useState(user.scopeLimit);
14+
15+
return (
16+
<TableRow key={user.id}>
17+
<TableData>
18+
<a href={`/user/${user.id}`}>{user.name}</a>
19+
</TableData>
20+
<TableData>
21+
{user.email}
22+
</TableData>
23+
<TableData>
24+
{user.githubId}
25+
</TableData>
26+
<TableData>
27+
{edit
28+
? (
29+
<input
30+
type="number"
31+
class="block w-16 p-1.5 text-right input-container input"
32+
disabled={processing}
33+
value={scopeLimit}
34+
onChange={(e) => setScopeLimit(+e.currentTarget.value)}
35+
required
36+
/>
37+
)
38+
: scopeLimit}
39+
</TableData>
40+
<TableData>
41+
{edit
42+
? (
43+
<select
44+
class="block w-16 p-1.5 input-container select"
45+
onChange={(e) => setIsStaff(e.currentTarget.value === "true")}
46+
value={String(isStaff)}
47+
disabled={processing}
48+
>
49+
<option value="false">false</option>
50+
<option value="true">true</option>
51+
</select>
52+
)
53+
: String(isStaff)}
54+
</TableData>
55+
<TableData>
56+
{edit
57+
? (
58+
<select
59+
class="block w-16 py-2 p-1.5 input-container select"
60+
onChange={(e) => setIsBlocked(e.currentTarget.value === "true")}
61+
value={String(isBlocked)}
62+
disabled={processing}
63+
>
64+
<option value="false">false</option>
65+
<option value="true">true</option>
66+
</select>
67+
)
68+
: String(isBlocked)}
69+
</TableData>
70+
<TableData title={new Date(user.createdAt).toISOString().slice(0, 10)}>
71+
{timeAgo(new Date(user.createdAt).getTime())}
72+
</TableData>
73+
<TableData class="relative whitespace-nowrap space-x-3 py-4 pl-3 pr-4 text-right text-sm font-semibold sm:pr-6">
74+
{edit
75+
? (
76+
<>
77+
<button
78+
type="button"
79+
disabled={processing}
80+
onClick={() => {
81+
setProcessing(true);
82+
api.patch(
83+
path`/admin/users/${user.id}`,
84+
{ isStaff, isBlocked, scopeLimit },
85+
).then((res) => {
86+
setProcessing(false);
87+
if (res.ok) {
88+
setEdit(false);
89+
} else {
90+
console.error(res);
91+
}
92+
});
93+
}}
94+
class="link disabled:text-jsr-gray-500 disabled:cursor-wait"
95+
>
96+
Save<span class="sr-only">, {user.name}</span>
97+
</button>
98+
99+
<button
100+
type="button"
101+
onClick={() => {
102+
setEdit(false);
103+
setIsStaff(user.isStaff);
104+
setIsBlocked(user.isBlocked);
105+
setScopeLimit(user.scopeLimit);
106+
}}
107+
class="link disabled:text-jsr-gray-500 disabled:cursor-wait"
108+
>
109+
Cancel<span class="sr-only">, {user.name}</span>
110+
</button>
111+
</>
112+
)
113+
: (
114+
<button
115+
type="button"
116+
onClick={() => setEdit(true)}
117+
class="link disabled:text-jsr-gray-500 disabled:cursor-wait"
118+
>
119+
Edit<span class="sr-only">, {user.name}</span>
120+
</button>
121+
)}
122+
</TableData>
123+
</TableRow>
124+
);
125+
}

frontend/islands/new.tsx

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,7 @@ import {
88
import { Package, Scope, User } from "../utils/api_types.ts";
99
import { api, path } from "../utils/api.ts";
1010
import { ComponentChildren } from "preact";
11-
import twas from "twas";
12-
import { TicketModal } from "./TicketModal.tsx";
11+
import { timeAgo } from "../utils/timeAgo.ts";
1312

1413
interface IconColorProps {
1514
done: Signal<unknown>;
@@ -463,7 +462,7 @@ export function CreatePackage({ scope, name, pkg, fromCli }: {
463462
</p>
464463
<p>{pkg.value.description || <i>No description</i>}</p>
465464
<p class="text-jsr-gray-500">
466-
Created {twas(new Date(pkg.value.createdAt).getTime())}.
465+
Created {timeAgo(pkg.value.createdAt)}.
467466
</p>
468467
{fromCli && (
469468
<p class="mt-2 text-jsr-gray-500">

frontend/routes/account/(_components)/AccountLayout.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// Copyright 2024 the JSR authors. All rights reserved. MIT license.
22
import { ComponentChildren } from "preact";
3-
import twas from "twas";
3+
import { timeAgo } from "../../../utils/timeAgo.ts";
44
import { AccountNav, AccountNavTab } from "./AccountNav.tsx";
55
import { FullUser, User } from "../../../utils/api_types.ts";
66
import { GitHubUserLink } from "../../../islands/GithubUserLink.tsx";
@@ -25,7 +25,7 @@ export function AccountLayout({ user, active, children }: AccountLayoutProps) {
2525
{user.name}
2626
</h1>
2727
<p class="text-xs text-jsr-gray-600">
28-
Created account {twas(new Date(user.createdAt).getTime())}
28+
Created account {timeAgo(new Date(user.createdAt).getTime())}
2929
</p>
3030
<p class="text-base mt-2">
3131
<GitHubUserLink user={user} />

0 commit comments

Comments
 (0)