forked from trent_larson/crowd-funder-for-time-pwa
save a profile blurb
This commit is contained in:
@@ -263,6 +263,47 @@
|
||||
</router-link>
|
||||
</div>
|
||||
|
||||
<!-- User Profile -->
|
||||
<div
|
||||
class="bg-slate-100 rounded-md overflow-hidden px-4 py-4 mt-8 mb-8"
|
||||
>
|
||||
<div v-if="loadingProfile" class="text-center mb-2">
|
||||
<fa icon="spinner" class="fa-spin text-slate-400"></fa> Loading
|
||||
profile...
|
||||
</div>
|
||||
<div v-else class="flex items-center mb-2">
|
||||
<span class="font-bold">Public Profile</span>
|
||||
<fa
|
||||
icon="circle-info"
|
||||
class="text-slate-400 fa-fw ml-2 cursor-pointer"
|
||||
@click="showProfileInfo"
|
||||
/>
|
||||
</div>
|
||||
<textarea
|
||||
v-model="userProfile"
|
||||
class="w-full h-32 p-2 border border-slate-300 rounded-md"
|
||||
placeholder="Write something about yourself for the public..."
|
||||
:readonly="loadingProfile || savingProfile"
|
||||
:class="{ 'bg-slate-100': loadingProfile || savingProfile }"
|
||||
></textarea>
|
||||
<button
|
||||
@click="saveProfile"
|
||||
class="mt-2 px-4 py-2 bg-gradient-to-b from-blue-400 to-blue-700 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] text-white rounded-md"
|
||||
:disabled="loadingProfile || savingProfile"
|
||||
:class="{
|
||||
'opacity-50 cursor-not-allowed': loadingProfile || savingProfile,
|
||||
}"
|
||||
>
|
||||
{{
|
||||
loadingProfile
|
||||
? "Loading..."
|
||||
: savingProfile
|
||||
? "Saving..."
|
||||
: "Save Profile"
|
||||
}}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div
|
||||
v-if="activeDid"
|
||||
id="sectionUsageLimits"
|
||||
@@ -819,6 +860,7 @@ import {
|
||||
} from "@/constants/app";
|
||||
import {
|
||||
db,
|
||||
logConsoleAndDb,
|
||||
retrieveSettingsForActiveAccount,
|
||||
updateAccountSettings,
|
||||
} from "@/db/index";
|
||||
@@ -830,8 +872,9 @@ import {
|
||||
} from "@/db/tables/settings";
|
||||
import {
|
||||
clearPasskeyToken,
|
||||
ErrorResponse,
|
||||
EndorserRateLimits,
|
||||
ErrorResponse,
|
||||
errorStringForLog,
|
||||
fetchEndorserRateLimits,
|
||||
fetchImageRateLimits,
|
||||
getHeaders,
|
||||
@@ -877,6 +920,7 @@ export default class AccountViewView extends Vue {
|
||||
isRegistered = false;
|
||||
limitsMessage = "";
|
||||
loadingLimits = false;
|
||||
loadingProfile = true;
|
||||
notifyingNewActivity = false;
|
||||
notifyingNewActivityTime = "";
|
||||
notifyingReminder = false;
|
||||
@@ -890,6 +934,7 @@ export default class AccountViewView extends Vue {
|
||||
profileImageUrl?: string;
|
||||
publicHex = "";
|
||||
publicBase64 = "";
|
||||
savingProfile = false;
|
||||
showAdvanced = false;
|
||||
showB64Copy = false;
|
||||
showContactGives = false;
|
||||
@@ -905,6 +950,7 @@ export default class AccountViewView extends Vue {
|
||||
warnIfTestServer = false;
|
||||
webPushServer = "";
|
||||
webPushServerInput = "";
|
||||
userProfile = "";
|
||||
|
||||
/**
|
||||
* Async function executed when the component is mounted.
|
||||
@@ -918,6 +964,38 @@ export default class AccountViewView extends Vue {
|
||||
// Initialize component state with values from the database or defaults
|
||||
await this.initializeState();
|
||||
await this.processIdentity();
|
||||
|
||||
// Load the user profile
|
||||
try {
|
||||
const headers = await getHeaders(this.activeDid);
|
||||
const response = await this.axios.get(
|
||||
this.apiServer + "/api/partner/user-profile/" + this.activeDid,
|
||||
{ headers },
|
||||
);
|
||||
if (response.status === 200) {
|
||||
this.userProfile = response.data.description || "";
|
||||
} else {
|
||||
// won't get here because axios throws an error instead
|
||||
throw Error("Unable to load profile.");
|
||||
}
|
||||
} catch (error) {
|
||||
if (error.status === 404) {
|
||||
// this is ok: the profile is not yet created
|
||||
} else {
|
||||
logConsoleAndDb("Error loading profile: " + errorStringForLog(error));
|
||||
this.$notify(
|
||||
{
|
||||
group: "alert",
|
||||
type: "danger",
|
||||
title: "Error Loading Profile",
|
||||
text: "Your server profile is not available.",
|
||||
},
|
||||
5000,
|
||||
);
|
||||
}
|
||||
} finally {
|
||||
this.loadingProfile = false;
|
||||
}
|
||||
} catch (error) {
|
||||
// this can happen when running automated tests in dev mode because notifications don't work
|
||||
console.error(
|
||||
@@ -1498,13 +1576,22 @@ export default class AccountViewView extends Vue {
|
||||
*/
|
||||
private handleRateLimitsError(error: unknown) {
|
||||
if (error instanceof AxiosError) {
|
||||
const data = error.response?.data as ErrorResponse;
|
||||
this.limitsMessage =
|
||||
(data?.error?.message as string) || "Bad server response.";
|
||||
console.error(
|
||||
"Got bad response retrieving limits, which usually means user isn't registered.",
|
||||
error,
|
||||
);
|
||||
if (error.status == 400 || error.status == 404) {
|
||||
// no worries: they probably just aren't registered and don't have any limits
|
||||
console.log(
|
||||
"Got 400 or 404 response retrieving limits which probably means they're not registered:",
|
||||
error,
|
||||
);
|
||||
this.limitsMessage = "No limits found, so no actions are allowed.";
|
||||
} else {
|
||||
const data = error.response?.data as ErrorResponse;
|
||||
this.limitsMessage =
|
||||
(data?.error?.message as string) || "Bad server response.";
|
||||
console.log(
|
||||
"Got bad response retrieving limits:",
|
||||
error,
|
||||
);
|
||||
}
|
||||
} else {
|
||||
this.limitsMessage = "Got an error retrieving limits.";
|
||||
console.error("Got some error retrieving limits:", error);
|
||||
@@ -1635,5 +1722,63 @@ export default class AccountViewView extends Vue {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
showProfileInfo() {
|
||||
this.$notify(
|
||||
{
|
||||
group: "alert",
|
||||
type: "info",
|
||||
title: "Public Profile Information",
|
||||
text: "This data will be published for all to see, so be careful what your write. Your ID will only be shared with people who you allow to see your activity.",
|
||||
},
|
||||
7000,
|
||||
);
|
||||
}
|
||||
|
||||
async saveProfile() {
|
||||
this.savingProfile = true;
|
||||
try {
|
||||
const headers = await getHeaders(this.activeDid);
|
||||
const response = await this.axios.post(
|
||||
this.apiServer + "/api/partner/user-profile",
|
||||
{
|
||||
description: this.userProfile,
|
||||
},
|
||||
{ headers },
|
||||
);
|
||||
if (response.status === 201) {
|
||||
this.$notify(
|
||||
{
|
||||
group: "alert",
|
||||
type: "success",
|
||||
title: "Profile Saved",
|
||||
text: "Your profile has been updated successfully.",
|
||||
},
|
||||
3000,
|
||||
);
|
||||
} else {
|
||||
// won't get here because axios throws an error on non-success
|
||||
throw Error("Profile not saved");
|
||||
}
|
||||
} catch (error) {
|
||||
logConsoleAndDb("Error saving profile: " + errorStringForLog(error));
|
||||
const errorMessage: string =
|
||||
error.response?.data?.error?.message ||
|
||||
error.response?.data?.error ||
|
||||
error.message ||
|
||||
"There was an error saving your profile.";
|
||||
this.$notify(
|
||||
{
|
||||
group: "alert",
|
||||
type: "danger",
|
||||
title: "Error Saving Profile",
|
||||
text: errorMessage,
|
||||
},
|
||||
3000,
|
||||
);
|
||||
} finally {
|
||||
this.savingProfile = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
Reference in New Issue
Block a user