Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 10 additions & 4 deletions types/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,12 +77,18 @@ func (e ErrorString) PrefixedError(s string) error {
}

// PrefixedError will return e with any "String" prefix removed and s prefixed instead. TODO: #107
func PrefixedError(e error, s string) error {
func PrefixedError(e error, prefix string) error {
if e == nil {
return nil
}

return errors.New(s + strings.TrimPrefix(e.Error(), "String"))
msg := strings.TrimPrefix(e.Error(), "String")

if !strings.HasSuffix(prefix, " ") {
prefix += " "
}

return errors.New(prefix + strings.ToLower(msg))
}

func (e ErrorString) ContextError(ctx ...any) error {
Expand All @@ -94,8 +100,8 @@ func (e ErrorString) ContextError(ctx ...any) error {
// Make the error singular if context is 1.
err := strings.TrimSuffix(e.Error(), ".")
if strings.HasSuffix(err, "s") && len(ctx) == 1 {
strings.TrimSuffix(err, "s")
}
err = strings.TrimSuffix(err, "s")
}

fmtSpace := func(s string) string {
if s == " " {
Expand Down
261 changes: 135 additions & 126 deletions ui/src/components/AccountBox.vue
Original file line number Diff line number Diff line change
Expand Up @@ -16,36 +16,36 @@ SPDX-License-Identifier: OSL-3.0
<div class="LayoutAccount__info_entry">
<!-- TODO: Add edit buttons -->
<header-row-box
class="LayoutAccount__info_entry_box"
style="margin-left: 0;"
header="Account"
icon="user"
:columns="['Profile', 'Username', 'Email']"
:rows="{
'Profile': getStore().accountJson.default_name,
'Username': getStore().accountJson.username,
'Email': getStore().accountJson.email,
}"
:links="{
'Profile': `/profile/${getStore().accountJson.id}`
}"
class="LayoutAccount__info_entry_box"
style="margin-left: 0"
header="Account"
icon="user"
:columns="['Profile', 'Username', 'Email']"
:rows="{
Profile: getStore().accountJson.default_name,
Username: getStore().accountJson.username,
Email: getStore().accountJson.email,
}"
:links="{
Profile: `/profile/${getStore().accountJson.id}`,
}"
/>

<div class="LayoutAccount_buttons">
<FormKit
type="button"
class="LayoutAccount__buttons_button"
label="Logout"
@click="logOut"
:disabled="getSession().activeSession === false"
type="button"
class="LayoutAccount__buttons_button"
label="Logout"
@click="logOut"
:disabled="getSession().activeSession === false"
/>
<FormKit
type="button"
style="background-color: var(--tr-error)"
class="LayoutAccount__buttons_button"
label="Delete Account"
@click="showDeleteForm"
:disabled="getSession().activeSession === false"
type="button"
style="background-color: var(--tr-error)"
class="LayoutAccount__buttons_button"
label="Delete Account"
@click="showDeleteForm"
:disabled="getSession().activeSession === false"
/>
</div>
</div>
Expand All @@ -54,44 +54,44 @@ SPDX-License-Identifier: OSL-3.0
</div>
</div>
<div v-show="getStore().showDeleteForm">

<div class="DefaultView__form">
<FormKit type="form" @submit="submitForm" #default="{ state: { valid } }" :actions="false">
<FormKit
type="email"
name="email"
id="email"
label="Email address"
help="The email associated with your account."
validation="required|email"
placeholder="lyv@effectindex.com"
type="email"
name="email"
id="email"
label="Email address"
help="The email associated with your account."
validation="required|email"
validation-visibility="live"
placeholder="lyv@effectindex.com"
/>

<FormKit
type="password"
name="password"
id="password"
label="Password"
help="The password associated with your account."
validation="required|length:8,32"
placeholder="----------"
type="password"
name="password"
id="password"
label="Password"
help="The password associated with your account."
validation="required|length:8,32"
validation-visibility="live"
placeholder="----------"
/>

<div class="LayoutAccount_buttons">
<FormKit
type="button"
class="LayoutAccount__buttons_button"
label="Back"
@click="hideDeleteForm"
:disabled="getSession().activeSession === false"
type="button"
class="LayoutAccount__buttons_button"
label="Back"
@click="hideDeleteForm"
:disabled="getSession().activeSession === false"
/>
<FormKit
type="submit"
style="background-color: var(--tr-error)"
class="LayoutAccount__buttons_button"
label="Delete Account"
data-next="true"
:disabled="!valid || getSession().activeSession === false"
type="submit"
style="background-color: var(--tr-error)"
class="LayoutAccount__buttons_button"
label="Delete Account"
data-next="true"
:disabled="!valid || getSession().activeSession === false"
/>
</div>
</FormKit>
Expand All @@ -113,25 +113,25 @@ export default {
components: { HeaderRowBox },
methods: {
getStore() {
return store
return store;
},
getSession() {
return sessionStore
return sessionStore;
},
isLoaded() {
return store.isLoaded()
}
}
}
return store.isLoaded();
},
},
};
</script>

<script async setup>
import { inject, ref } from "vue";
import { handleMessageError, setMessage } from "@/assets/lib/message_util";
import log from "@/assets/lib/logger";

const router = inject('router')
const axios = inject('axios')
const router = inject("router");
const axios = inject("axios");

const messageSuccess = "Account successfully deleted!<br>You will be redirected to the home page in 3 seconds.";
const messageLoggedOut = "Logged out successfully!<br>You will be redirected to login in 3 seconds.";
Expand All @@ -141,101 +141,110 @@ let submitting = ref(false);
let ranSetup = false;

const submitForm = async (fields) => {
log("submitForm", fields)
log("submitForm", fields);

submitting.value = true;

axios.delete('/account', { data: fields }).then(function (response) {
success.value = response.status === 200;
submitting.value = false;
if (success.value === true) {
store.showDeleteForm = false;
sessionStore.invalidateSession();
}
setMessage(response.data.msg, messageSuccess, success.value, router, '/', 3000);
}).catch(function (error) {
success.value = error.response.status === 200;
submitting.value = false;
if (success.value === true) {
store.showDeleteForm = false;
sessionStore.invalidateSession();
}
setMessage(error.response.data.msg, messageSuccess, success.value, router, '/', 3000);
handleMessageError(error);
})
}
axios
.delete("/account", { data: fields })
.then(function (response) {
success.value = response.status === 200;
submitting.value = false;
if (success.value === true) {
store.showDeleteForm = false;
sessionStore.invalidateSession();
}
setMessage(response.data.msg, messageSuccess, success.value, router, "/", 3000);
})
.catch(function (error) {
success.value = error.response.status === 200;
submitting.value = false;
if (success.value === true) {
store.showDeleteForm = false;
sessionStore.invalidateSession();
}
setMessage(error.response.data.msg, messageSuccess, success.value, router, "/", 3000);
handleMessageError(error);
});
};

const showDeleteForm = (e) => {
store.showDeleteForm = true
}
store.showDeleteForm = true;
};

const hideDeleteForm = (e) => {
store.showDeleteForm = false
}
store.showDeleteForm = false;
};

const logOut = (e) => {
submitting.value = true

axios.delete('/session').then(function (response) {
loggedOut.value = response.status === 200;
submitting.value = false;
if (loggedOut.value === true) {
store.showDeleteForm = false;
sessionStore.invalidateSession();
}
setMessage(response.data.msg, messageLoggedOut, loggedOut.value, router, '/login', 3000);
}).catch(function (error) {
loggedOut.value = error.response.status === 200;
submitting.value = false;
if (loggedOut.value === true) {
store.showDeleteForm = false;
sessionStore.invalidateSession();
}
setMessage(error.response.data.msg, messageLoggedOut, loggedOut.value, router, '/login', 3000);
handleMessageError(error);
})
}
submitting.value = true;

axios
.delete("/session")
.then(function (response) {
loggedOut.value = response.status === 200;
submitting.value = false;
if (loggedOut.value === true) {
store.showDeleteForm = false;
sessionStore.invalidateSession();
}
setMessage(response.data.msg, messageLoggedOut, loggedOut.value, router, "/login", 3000);
})
.catch(function (error) {
loggedOut.value = error.response.status === 200;
submitting.value = false;
if (loggedOut.value === true) {
store.showDeleteForm = false;
sessionStore.invalidateSession();
}
setMessage(error.response.data.msg, messageLoggedOut, loggedOut.value, router, "/login", 3000);
handleMessageError(error);
});
};

if (ranSetup !== true) {
ranSetup = true

await axios.get('/account').then(function (response) {
store.updateData(response.status, response.data)
setMessage(response.data.msg, "", store.apiSuccess);
}).catch(function (error) {
log("error", error)
store.updateData(error.response.status, error.response.data)
setMessage(error.response.data.msg, "", store.apiSuccess);
handleMessageError(error);
})
ranSetup = true;

await axios
.get("/account")
.then(function (response) {
store.updateData(response.status, response.data);
setMessage(response.data.msg, "", store.apiSuccess);
})
.catch(function (error) {
log("error", error);
store.updateData(error.response.status, error.response.data);
setMessage(error.response.data.msg, "", store.apiSuccess);
handleMessageError(error);
});
}
</script>
<style scoped>
.LayoutAccount__main {
text-align: left;
text-align: left;
}

.LayoutAccount__main h1 {
text-align: center;
text-align: center;
}

.LayoutAccount__account {
max-width: 25em;
margin: auto;
max-width: 25em;
margin: auto;
}

.LayoutAccount__info_entry_box {
margin-bottom: 1em;
margin-bottom: 1em;
}

.LayoutAccount_buttons {
display: flex;
flex-wrap: wrap;
flex-direction: row;
justify-content: left;
display: flex;
flex-wrap: wrap;
flex-direction: row;
justify-content: left;
}

.LayoutAccount__buttons_button {
flex-grow: 1;
flex-grow: 1;
}
</style>
</style>
Loading