Added handle editing with warning.
This commit is contained in:
parent
8d08cc435a
commit
72e7a8fd6e
2 changed files with 134 additions and 3 deletions
|
@ -4,6 +4,7 @@ import { useRefresh } from "../../../lib/RefreshContext";
|
|||
|
||||
interface User {
|
||||
did: string;
|
||||
handle?: string;
|
||||
displayName?: string;
|
||||
description?: string;
|
||||
avatar?: {
|
||||
|
@ -14,6 +15,7 @@ interface User {
|
|||
createdAt: string;
|
||||
}
|
||||
|
||||
|
||||
interface RepoResponse {
|
||||
cursor: string;
|
||||
repos: {
|
||||
|
@ -79,6 +81,16 @@ export default function UserList() {
|
|||
show: false,
|
||||
user: null,
|
||||
});
|
||||
const [editModal, setEditModal] = useState<{
|
||||
show: boolean;
|
||||
user: User | null;
|
||||
newHandle: string;
|
||||
}>({
|
||||
show: false,
|
||||
user: null,
|
||||
newHandle: "",
|
||||
});
|
||||
|
||||
|
||||
const resetState = () => {
|
||||
setUsers([]);
|
||||
|
@ -108,6 +120,7 @@ export default function UserList() {
|
|||
const data = await response.json();
|
||||
return {
|
||||
did,
|
||||
handle: data.value.handle,
|
||||
displayName: data.value.displayName,
|
||||
description: data.value.description,
|
||||
avatar: data.value.avatar,
|
||||
|
@ -210,6 +223,48 @@ export default function UserList() {
|
|||
}
|
||||
};
|
||||
|
||||
const updateUserHandle = async (did: string, newHandle: string) => {
|
||||
try {
|
||||
setLoading(true);
|
||||
setError(null);
|
||||
|
||||
const baseUrl = await Settings.getServiceUrl();
|
||||
if (!baseUrl) throw new Error("Service URL not configured");
|
||||
|
||||
const headers = {
|
||||
Authorization: await getAuthHeader(),
|
||||
"Content-Type": "application/json",
|
||||
};
|
||||
|
||||
const response = await fetch(
|
||||
`${baseUrl}/xrpc/com.atproto.admin.updateAccountHandle`,
|
||||
{
|
||||
method: "POST",
|
||||
headers,
|
||||
body: JSON.stringify({
|
||||
did,
|
||||
handle: newHandle,
|
||||
}),
|
||||
}
|
||||
);
|
||||
|
||||
if (!response.ok) {
|
||||
const errorText = await response.text();
|
||||
console.error("Error response:", errorText);
|
||||
throw new Error(
|
||||
`Failed to update handle: ${response.status} ${response.statusText}`
|
||||
);
|
||||
}
|
||||
|
||||
await fetchUsers(); // Refresh the user list after successful update
|
||||
} catch (err) {
|
||||
console.error("Update handle error:", err);
|
||||
setError(err instanceof Error ? err.message : "Failed to update handle");
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
async function checkSettings() {
|
||||
try {
|
||||
|
@ -304,6 +359,69 @@ export default function UserList() {
|
|||
</button>
|
||||
</div>
|
||||
|
||||
{/* Edit Handle Modal */}
|
||||
{editModal.show && editModal.user && (
|
||||
<dialog className="modal modal-open">
|
||||
<div className="modal-box">
|
||||
<h3 className="font-bold text-lg">Edit Handle</h3>
|
||||
<p className="py-4">
|
||||
Update handle for{" "}
|
||||
<span className="font-semibold">
|
||||
{editModal.user.displayName || "Anonymous"}
|
||||
</span>.
|
||||
<br />
|
||||
<br />
|
||||
<span className="font-bold">**Note that you will need a "_atproto" TXT record with the corresponding "did=SOME_DID_NUMBER" before changing your handle to a subdomain of your PDS domain.</span>
|
||||
</p>
|
||||
<div className="form-control">
|
||||
<label className="label">
|
||||
<span className="label-text">New Handle</span>
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
placeholder="new.handle.pds.domain"
|
||||
className="input input-bordered"
|
||||
value={editModal.newHandle}
|
||||
onChange={(e) =>
|
||||
setEditModal({ ...editModal, newHandle: e.target.value })
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
<div className="modal-action">
|
||||
<button
|
||||
className="btn"
|
||||
onClick={() =>
|
||||
setEditModal({ show: false, user: null, newHandle: "" })
|
||||
}
|
||||
>
|
||||
Cancel
|
||||
</button>
|
||||
<button
|
||||
className="btn btn-primary"
|
||||
onClick={async () => {
|
||||
if (editModal.user && editModal.newHandle) {
|
||||
await updateUserHandle(editModal.user.did, editModal.newHandle);
|
||||
setEditModal({ show: false, user: null, newHandle: "" });
|
||||
}
|
||||
}}
|
||||
disabled={!editModal.newHandle}
|
||||
>
|
||||
Update Handle
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<form method="dialog" className="modal-backdrop">
|
||||
<button
|
||||
onClick={() =>
|
||||
setEditModal({ show: false, user: null, newHandle: "" })
|
||||
}
|
||||
>
|
||||
close
|
||||
</button>
|
||||
</form>
|
||||
</dialog>
|
||||
)}
|
||||
|
||||
{/* Confirmation Modal */}
|
||||
{deleteConfirmation.show && deleteConfirmation.user && (
|
||||
<dialog className="modal modal-open">
|
||||
|
@ -396,6 +514,9 @@ export default function UserList() {
|
|||
<h2 className="text-lg font-semibold">
|
||||
{user.displayName || "Anonymous"}
|
||||
</h2>
|
||||
<div className="font-mono text-sm opacity-70 mt-1">
|
||||
{user.handle}
|
||||
</div>
|
||||
<div className="font-mono text-sm opacity-70 mt-1">
|
||||
{user.did}
|
||||
</div>
|
||||
|
@ -405,11 +526,21 @@ export default function UserList() {
|
|||
</p>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className="flex flex-col gap-2">
|
||||
<button
|
||||
onClick={() =>
|
||||
setDeleteConfirmation({ show: true, user })
|
||||
}
|
||||
onClick={() => setEditModal({
|
||||
show: true,
|
||||
user,
|
||||
newHandle: user.handle || ""
|
||||
})}
|
||||
className="btn btn-sm btn-primary"
|
||||
disabled={loading}
|
||||
>
|
||||
Edit
|
||||
</button>
|
||||
<button
|
||||
onClick={() => setDeleteConfirmation({ show: true, user })}
|
||||
className="btn btn-sm btn-error"
|
||||
disabled={loading}
|
||||
>
|
||||
|
|
Loading…
Add table
Reference in a new issue