Added a global `notify` method via Nuxt plugin to replace `useNotification`. Improved messaging structure by embedding progress bars and handled dynamic durations. Updated usage across composables and components for consistency. - Replaced `useNotification` with `$notify` in all applicable files. - Updated `app.config.ts` to support customizable notification positions. - Refactored affected composables for simplified notification calls. - Enhanced progress indicator display within notifications. Breaking Changes: `useNotification` is removed, requiring migration to the new `$notify` API.
242 lines
No EOL
5.2 KiB
Vue
242 lines
No EOL
5.2 KiB
Vue
<template>
|
|
<div class="settings">
|
|
<div class="settings__top">
|
|
<div class="settings__top-left">
|
|
<div class="settings__avatar">
|
|
<input type="file" id="avatar" @change="uploadAvatar" />
|
|
<label for="avatar">
|
|
<nuxt-img
|
|
class="settings__avatar-image"
|
|
v-if="user?.avatar"
|
|
:src="user?.avatar"
|
|
alt="avatar"
|
|
format="webp"
|
|
densities="x1"
|
|
/>
|
|
<icon name="clarity:avatar-line" size="40" v-else />
|
|
<span class="settings__avatar-inner">
|
|
<icon name="material-symbols:upload" size="40" />
|
|
</span>
|
|
</label>
|
|
</div>
|
|
<div class="settings__top-inner">
|
|
<h2>{{ user?.firstName }} {{ user?.lastName }}</h2>
|
|
<p>{{ t('profile.settings.joinData') }}: {{ joinData }}</p>
|
|
</div>
|
|
</div>
|
|
<el-tooltip
|
|
:content="t('profile.settings.referralTooltip')"
|
|
placement="top-end"
|
|
:disabled="finishedOrdersQuantity > 0"
|
|
>
|
|
<button
|
|
class="settings__button"
|
|
@click="copyReferral"
|
|
:disabled="finishedOrdersQuantity === 0"
|
|
>
|
|
<icon name="material-symbols:content-copy" size="20" />
|
|
{{ t('profile.settings.copyReferral') }}
|
|
</button>
|
|
</el-tooltip>
|
|
</div>
|
|
<div class="settings__main">
|
|
<p>{{ t('profile.settings.accountInfo') }}</p>
|
|
<forms-update />
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import {usePageTitle} from '@composables/utils';
|
|
import { useDate } from '@composables/date';
|
|
import {useAvatarUpload} from '@composables/user';
|
|
|
|
const {t} = useI18n();
|
|
const userStore = useUserStore();
|
|
const { $appHelpers, $notify } = useNuxtApp();
|
|
|
|
const { uploadAvatar } = useAvatarUpload();
|
|
|
|
const cookieLocale = useCookie(
|
|
$appHelpers. COOKIES_LOCALE_KEY,
|
|
{
|
|
default: () => $appHelpers.DEFAULT_LOCALE,
|
|
path: '/'
|
|
}
|
|
);
|
|
|
|
const user = computed(() => userStore.user);
|
|
const finishedOrdersQuantity = computed(() => userStore.finishedOrdersQuantity);
|
|
const joinData = computed(() => {
|
|
return useDate(
|
|
user.value?.dateJoined, cookieLocale.value
|
|
);
|
|
});
|
|
|
|
const referralLink = computed(() => {
|
|
if (finishedOrdersQuantity.value > 0) {
|
|
return `https://${$appHelpers.APP_DOMAIN}/${$appHelpers.DEFAULT_LOCALE}/?referrer=` + user.value?.uuid;
|
|
} else {
|
|
return `https://${$appHelpers.APP_DOMAIN}/${$appHelpers.DEFAULT_LOCALE}/`;
|
|
}
|
|
});
|
|
|
|
const copyReferral = () => {
|
|
if (finishedOrdersQuantity.value > 0) {
|
|
navigator.clipboard.writeText(referralLink.value)
|
|
.then(() => {
|
|
$notify({
|
|
message: t('popup.success.referralCopy'),
|
|
type: 'success'
|
|
});
|
|
})
|
|
.catch(err => {
|
|
console.error(err);
|
|
});
|
|
}
|
|
};
|
|
|
|
const { setPageTitle } = usePageTitle();
|
|
|
|
setPageTitle(t('breadcrumbs.settings'));
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
.settings {
|
|
background-color: $white;
|
|
width: 100%;
|
|
border: 1px solid #e5e7eb;
|
|
border-radius: 8px;
|
|
height: fit-content;
|
|
|
|
&__top {
|
|
display: flex;
|
|
align-items: flex-start;
|
|
justify-content: space-between;
|
|
gap: 25px;
|
|
padding: 24px 32px;
|
|
border-bottom: 1px solid #e5e7eb;
|
|
|
|
&-left {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 25px;
|
|
}
|
|
|
|
&-inner {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 5px;
|
|
|
|
& h2 {
|
|
color: #111827;
|
|
font-family: "Playfair Display", sans-serif;
|
|
font-size: 24px;
|
|
font-weight: 700;
|
|
}
|
|
|
|
& p {
|
|
color: #4b5563;
|
|
font-size: 16px;
|
|
font-weight: 400;
|
|
}
|
|
}
|
|
}
|
|
|
|
&__avatar {
|
|
width: 80px;
|
|
height: 80px;
|
|
border-radius: 50%;
|
|
border: 2px solid #e5e7eb;
|
|
background-color: rgba($accent, 0.2);
|
|
position: relative;
|
|
overflow: hidden;
|
|
|
|
@include hover {
|
|
.settings__avatar-inner {
|
|
opacity: 1;
|
|
}
|
|
}
|
|
|
|
& label {
|
|
cursor: pointer;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
height: 100%;
|
|
|
|
& span {
|
|
color: #a9a9a9;
|
|
}
|
|
}
|
|
|
|
&-image {
|
|
width: 100%;
|
|
height: 100%;
|
|
object-fit: cover;
|
|
}
|
|
|
|
&-inner {
|
|
position: absolute;
|
|
z-index: 1;
|
|
width: 100%;
|
|
height: 100%;
|
|
inset: 0;
|
|
display: grid;
|
|
place-items: center;
|
|
opacity: 0;
|
|
transition: 0.2s;
|
|
background-color: rgba(0, 0, 0, 0.5);
|
|
|
|
& span {
|
|
color: $white !important;
|
|
}
|
|
}
|
|
|
|
& input {
|
|
display: none;
|
|
}
|
|
}
|
|
|
|
&__button {
|
|
cursor: pointer;
|
|
border-radius: $default_border_radius;
|
|
padding: 5px 15px;
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 10px;
|
|
transition: 0.2s;
|
|
|
|
color: #4b5563;
|
|
font-size: 16px;
|
|
font-weight: 500;
|
|
|
|
@include hover {
|
|
background-color: #c0c0c0;
|
|
color: #373f49;
|
|
}
|
|
|
|
&:disabled {
|
|
cursor: not-allowed;
|
|
|
|
@include hover {
|
|
background-color: #c0c0c0;
|
|
color: #4b5563;
|
|
}
|
|
}
|
|
}
|
|
|
|
&__main {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 25px;
|
|
padding: 24px 32px;
|
|
|
|
& p {
|
|
font-size: 24px;
|
|
font-weight: 600;
|
|
color: $accentDark;
|
|
}
|
|
}
|
|
}
|
|
</style> |