feat(frontend): you can now update your icon
This commit is contained in:
parent
3cccc18e9a
commit
5884407f35
3 changed files with 64 additions and 11 deletions
|
|
@ -31,6 +31,19 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div id="iconBox" class="mb-1 grid grid-cols-[auto_1fr] gap-2 hidden">
|
||||||
|
<div id="viewIconBox" class="h-[128px] w-[128px] p-2 border-gray-700 border-2 rounded-lg">
|
||||||
|
<img/>
|
||||||
|
</div>
|
||||||
|
<div id="updateIconBox">
|
||||||
|
<form id="updateIconForm" class="flex flex-col justify-evenly h-full">
|
||||||
|
<input type="file" name="upload" accept="image/png, image/jpeg" class="text-black border-black border-2 rounded-lg px-4 w-[230px]"></input>
|
||||||
|
<span class="text-black font-base">Select Image</span>
|
||||||
|
<button type="submit" class="w-full bg-blue-600 text-white py-2 rounded hover:bg-blue-700"> Update </button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<!-- Display Name -->
|
<!-- Display Name -->
|
||||||
<div id="displayNameWrapper" class="py-2">
|
<div id="displayNameWrapper" class="py-2">
|
||||||
<label class="block font-medium mb-1 text-gray-700">Display Name</label>
|
<label class="block font-medium mb-1 text-gray-700">Display Name</label>
|
||||||
|
|
@ -52,8 +65,7 @@
|
||||||
<label class="block font-medium mb-1 text-gray-700">Description</label>
|
<label class="block font-medium mb-1 text-gray-700">Description</label>
|
||||||
<input id="descBox" type="text" placeholder="Description..." name="Description"
|
<input id="descBox" type="text" placeholder="Description..." name="Description"
|
||||||
class="w-full px-4 py-2 border border-gray-300 text-gray-700 rounded-xl focus:outline-none focus:ring-2 focus:ring-blue-500" />
|
class="w-full px-4 py-2 border border-gray-300 text-gray-700 rounded-xl focus:outline-none focus:ring-2 focus:ring-blue-500" />
|
||||||
<button id="descButton"
|
<button id="descButton" class="w-full bg-blue-600 text-white py-2 rounded hover:bg-blue-700">Update</button>
|
||||||
class="w-full bg-blue-600 text-white py-2 rounded hover:bg-blue-700">Update</button>
|
|
||||||
</div>
|
</div>
|
||||||
<!-- TOTP -->
|
<!-- TOTP -->
|
||||||
<div class="border rounded p-4" id="totpWrapper" hidden>
|
<div class="border rounded p-4" id="totpWrapper" hidden>
|
||||||
|
|
|
||||||
|
|
@ -40,6 +40,45 @@ function removeBgColor(...elem: HTMLElement[]) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function setup_profile_image(container: HTMLDivElement, url: string) {
|
||||||
|
let imgNode = container.querySelector<HTMLImageElement>("img");
|
||||||
|
let formNode = container.querySelector<HTMLFormElement>("form");
|
||||||
|
if (!imgNode || !formNode) return;
|
||||||
|
imgNode.src = url;
|
||||||
|
container.classList.remove("hidden");
|
||||||
|
formNode.addEventListener("submit", async (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
let form = e.target;
|
||||||
|
if (!form) return;
|
||||||
|
let data = new FormData(form as HTMLFormElement);
|
||||||
|
let req = await fetch("/api/icons/set", {
|
||||||
|
body: data,
|
||||||
|
method: "POST",
|
||||||
|
});
|
||||||
|
if (req.status === 200 || req.status === 400) {
|
||||||
|
let json = await req.json();
|
||||||
|
if (!("kind" in json) || !("msg" in json))
|
||||||
|
return showError("Unknown Error");
|
||||||
|
if (typeof json.kind !== "string" || typeof json.msg !== "string")
|
||||||
|
return showError("Unknown Error");
|
||||||
|
const pjson: { kind: string; msg: string } = json;
|
||||||
|
if (pjson.kind === "success") {
|
||||||
|
showSuccess("Updated image !");
|
||||||
|
return handleRoute();
|
||||||
|
} else {
|
||||||
|
console.log(`Failed to upload image: ${pjson.msg}`);
|
||||||
|
showError("Failed to change image");
|
||||||
|
}
|
||||||
|
} if (req.status === 413)
|
||||||
|
{
|
||||||
|
showError("Image too big");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
showError("Unknown Error");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
async function route(url: string, _args: { [k: string]: string }) {
|
async function route(url: string, _args: { [k: string]: string }) {
|
||||||
setTitle("Edit Profile");
|
setTitle("Edit Profile");
|
||||||
return {
|
return {
|
||||||
|
|
@ -99,8 +138,7 @@ async function route(url: string, _args: { [k: string]: string }) {
|
||||||
|
|
||||||
let descWrapper =
|
let descWrapper =
|
||||||
app.querySelector<HTMLDivElement>("#descWrapper")!;
|
app.querySelector<HTMLDivElement>("#descWrapper")!;
|
||||||
let descBox =
|
let descBox = app.querySelector<HTMLInputElement>("#descBox")!;
|
||||||
app.querySelector<HTMLInputElement>("#descBox")!;
|
|
||||||
let descButton =
|
let descButton =
|
||||||
app.querySelector<HTMLButtonElement>("#descButton")!;
|
app.querySelector<HTMLButtonElement>("#descButton")!;
|
||||||
|
|
||||||
|
|
@ -126,6 +164,8 @@ async function route(url: string, _args: { [k: string]: string }) {
|
||||||
let totpWrapper =
|
let totpWrapper =
|
||||||
app.querySelector<HTMLDivElement>("#totpWrapper")!;
|
app.querySelector<HTMLDivElement>("#totpWrapper")!;
|
||||||
|
|
||||||
|
let imgBox = app.querySelector<HTMLDivElement>("#iconBox")!;
|
||||||
|
|
||||||
descBox.value = user.desc;
|
descBox.value = user.desc;
|
||||||
|
|
||||||
if (user.guest) {
|
if (user.guest) {
|
||||||
|
|
@ -138,10 +178,7 @@ async function route(url: string, _args: { [k: string]: string }) {
|
||||||
descButton,
|
descButton,
|
||||||
);
|
);
|
||||||
|
|
||||||
descButton.classList.add(
|
descButton.classList.add("bg-gray-700", "hover:bg-gray-700");
|
||||||
"bg-gray-700",
|
|
||||||
"hover:bg-gray-700",
|
|
||||||
);
|
|
||||||
descButton.disabled = true;
|
descButton.disabled = true;
|
||||||
descBox.disabled = true;
|
descBox.disabled = true;
|
||||||
|
|
||||||
|
|
@ -174,6 +211,7 @@ async function route(url: string, _args: { [k: string]: string }) {
|
||||||
passwordWrapper.hidden = false;
|
passwordWrapper.hidden = false;
|
||||||
|
|
||||||
accountTypeBox.innerText = "Normal";
|
accountTypeBox.innerText = "Normal";
|
||||||
|
setup_profile_image(imgBox, `/icons/${user.id}`);
|
||||||
} else if (
|
} else if (
|
||||||
!isNullish(user.selfInfo?.providerId) &&
|
!isNullish(user.selfInfo?.providerId) &&
|
||||||
!isNullish(user.selfInfo?.providerUser)
|
!isNullish(user.selfInfo?.providerUser)
|
||||||
|
|
@ -195,6 +233,7 @@ async function route(url: string, _args: { [k: string]: string }) {
|
||||||
totpWrapper.hidden = true;
|
totpWrapper.hidden = true;
|
||||||
|
|
||||||
accountTypeBox.innerText = "Provider";
|
accountTypeBox.innerText = "Provider";
|
||||||
|
setup_profile_image(imgBox, `/icons/${user.id}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---- Update UI ----
|
// ---- Update UI ----
|
||||||
|
|
@ -269,12 +308,13 @@ async function route(url: string, _args: { [k: string]: string }) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
descButton.onclick = async () => {
|
descButton.onclick = async () => {
|
||||||
let req = await client.changeDesc({ changeDescRequest: { desc: descBox.value } });
|
let req = await client.changeDesc({
|
||||||
|
changeDescRequest: { desc: descBox.value },
|
||||||
|
});
|
||||||
if (req.kind === "success") {
|
if (req.kind === "success") {
|
||||||
showSuccess("Successfully changed description");
|
showSuccess("Successfully changed description");
|
||||||
handleRoute();
|
handleRoute();
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
showError(`Failed to update`);
|
showError(`Failed to update`);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -6,4 +6,5 @@ location /api/icons/ {
|
||||||
location /icons/ {
|
location /icons/ {
|
||||||
root /volumes/;
|
root /volumes/;
|
||||||
default_type image/png;
|
default_type image/png;
|
||||||
|
add_header Cache-Control "max-age=30";
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue