Adds error handling for unique index on Creator's Name
This commit is contained in:
@@ -25,6 +25,7 @@ import PaymentCompleted from '../views/PaymentCompleted.vue';
|
||||
import PaymentFailed from "@/views/PaymentFailed.vue";
|
||||
import Home from '../views/main/Home.vue';
|
||||
import Wallet from '../views/main/Wallet.vue';
|
||||
import CreateCreator from "@/views/profile/creators/CreateCreator.vue";
|
||||
|
||||
const routes = [
|
||||
{
|
||||
@@ -160,6 +161,12 @@ const routes = [
|
||||
component: ProfilePage,
|
||||
meta: { requiresAuth: true },
|
||||
},
|
||||
{
|
||||
path: '/create-creator',
|
||||
name: 'create-creator',
|
||||
component: CreateCreator,
|
||||
meta: { requiresAuth: true },
|
||||
},
|
||||
];
|
||||
|
||||
const router = createRouter({
|
||||
|
||||
@@ -112,9 +112,12 @@ initializeLocale();
|
||||
</v-btn>
|
||||
</router-link>
|
||||
|
||||
<router-link v-else-if="authStore.isAuthenticated" class="w-full justify-start"
|
||||
to="/profile?target=CreatorPage">
|
||||
<v-btn class="w-full" variant="plain" :class="!sideBarStore.isOpen ? 'my-2' : ''"><span v-if="sideBarStore.isOpen">Activer votre page</span></v-btn>
|
||||
<router-link v-else-if="authStore.isAuthenticated"
|
||||
class="w-full justify-start"
|
||||
to="/create-creator">
|
||||
<v-btn class="w-full" variant="plain" :class="!sideBarStore.isOpen ? 'my-2' : ''">
|
||||
<span v-if="sideBarStore.isOpen">Activer votre page</span>
|
||||
</v-btn>
|
||||
</router-link>
|
||||
|
||||
<div v-if="authStore.isAuthenticated">
|
||||
|
||||
@@ -1,52 +1,75 @@
|
||||
<script setup>
|
||||
import {ref} from 'vue'
|
||||
import {useUserProfileStore} from "@/stores/userProfileStore.js";
|
||||
import {useCreatorProfileStore} from "@/stores/creatorProfileStore.js";
|
||||
import {useClient} from "@/plugins/api.js";
|
||||
import {useRouter} from "vue-router";
|
||||
|
||||
const emits = defineEmits(['requestAccept', 'requestCancel'])
|
||||
const creatorName = ref('');
|
||||
const errorMessage = ref('');
|
||||
const isLoading = ref(false);
|
||||
|
||||
const creatorName = ref('')
|
||||
const router = useRouter();
|
||||
const creatorProfileStore = useCreatorProfileStore();
|
||||
const userProfileStore = useUserProfileStore();
|
||||
|
||||
function requestCancel() {
|
||||
emits('requestCancel')
|
||||
async function createAccount() {
|
||||
const client = useClient();
|
||||
try {
|
||||
errorMessage.value = '';
|
||||
isLoading.value = true;
|
||||
const normalizedCreatorName = creatorName.value.toLowerCase();
|
||||
await client.post('/api/creators', {
|
||||
creatorId: userProfileStore.user.id,
|
||||
name: normalizedCreatorName,
|
||||
});
|
||||
await creatorProfileStore.fetchCurrentCreatorProfile();
|
||||
await router.push(`/@${normalizedCreatorName}`);
|
||||
} catch (error) {
|
||||
if (error?.response?.data?.errors) {
|
||||
errorMessage.value = error.response.data.errors[0]?.['reason'] || 'An unexpected error occurred.';
|
||||
} else {
|
||||
errorMessage.value = error?.response?.data?.message || error.message || 'An unexpected error occurred.';
|
||||
}
|
||||
} finally {
|
||||
isLoading.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
function requestAccept() {
|
||||
emits('requestAccept', creatorName.value)
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="text-center">
|
||||
<div class="py-2 text-2xl font-bold flex flex-row items-center">
|
||||
<div class="flex-grow text-center">Devenez Créateur</div>
|
||||
<v-btn icon @click="requestCancel" class="ml-auto" variant="text">
|
||||
<v-icon>mdi-close</v-icon>
|
||||
</v-btn>
|
||||
</div>
|
||||
|
||||
<v-text-field
|
||||
variant="outlined"
|
||||
v-model="creatorName"
|
||||
label="Nom de créateur"
|
||||
outlined
|
||||
></v-text-field>
|
||||
|
||||
<div class="flex flex-row justify-end gap-2">
|
||||
<v-btn
|
||||
variant="flat"
|
||||
@click="requestCancel"
|
||||
:style="{ borderColor: 'rgb(159, 76, 173)', color: 'rgb(159, 76, 173)' }"
|
||||
<div class="flex flex-column justify-end gap-2">
|
||||
<v-alert
|
||||
v-if="!!errorMessage"
|
||||
dense
|
||||
outlined
|
||||
text
|
||||
type="error"
|
||||
>
|
||||
Annuler
|
||||
</v-btn>
|
||||
{{ errorMessage }}
|
||||
</v-alert>
|
||||
|
||||
<v-btn
|
||||
<v-text-field
|
||||
variant="outlined"
|
||||
@click="requestAccept"
|
||||
:style="{ borderColor: 'rgb(159, 76, 173)', color: 'rgb(159, 76, 173)' }"
|
||||
>
|
||||
Créer
|
||||
</v-btn>
|
||||
v-model="creatorName"
|
||||
label="Nom de créateur"
|
||||
outlined
|
||||
></v-text-field>
|
||||
<div class="flex flex-row justify-end gap-2">
|
||||
|
||||
<v-btn
|
||||
:disabled="isLoading"
|
||||
variant="outlined"
|
||||
@click="createAccount"
|
||||
:style="{ borderColor: 'rgb(159, 76, 173)', color: 'rgb(159, 76, 173)' }"
|
||||
>
|
||||
Créer
|
||||
</v-btn>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -1,14 +1,11 @@
|
||||
<script setup>
|
||||
import XIcon from '@/assets/icons/x.svg';
|
||||
import { useClient } from '@/plugins/api.js';
|
||||
import { useCreatorProfileStore } from '@/stores/creatorProfileStore.js';
|
||||
import { useUserProfileStore } from '@/stores/userProfileStore.js';
|
||||
import ChangeStripeID from '@/views/profile/creators/ChangeStripeID.vue';
|
||||
import ChangeTitle from '@/views/profile/creators/ChangeTitle.vue';
|
||||
import { computed, ref } from 'vue';
|
||||
import BannerPicker from './BannerPicker.vue';
|
||||
import ColorsPicker from './ColorsPicker.vue';
|
||||
import CreateCreator from './CreateCreator.vue';
|
||||
import LogoPicker from './LogoPicker.vue';
|
||||
import Socials from './Socials.vue';
|
||||
|
||||
@@ -32,26 +29,10 @@ const componentsMap = {
|
||||
LogoPicker,
|
||||
Socials,
|
||||
ColorsPicker,
|
||||
CreateCreator,
|
||||
ChangeTitle,
|
||||
ChangeStripeID,
|
||||
};
|
||||
|
||||
async function requestAccept(creatorName) {
|
||||
const userProfileStore = useUserProfileStore();
|
||||
const client = useClient();
|
||||
const response = await client.post('/api/creators', {
|
||||
creatorId: userProfileStore.user.id,
|
||||
name: creatorName,
|
||||
});
|
||||
if (response.status >= 200 && response.status < 300) {
|
||||
currentComponent.value = null;
|
||||
dialog.value = false;
|
||||
await creatorProfileStore.fetchCurrentCreatorProfile();
|
||||
} else {
|
||||
console.log(`An issue while creating the creator: ${response.statusText}`);
|
||||
}
|
||||
}
|
||||
|
||||
function requestCancel() {
|
||||
currentComponent.value = null;
|
||||
@@ -314,31 +295,6 @@ const closeDialog = () => {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-else class="w-full max-w-[800px]">
|
||||
<div class="my-10 border rounded bg-white shadow">
|
||||
<div class="py-5 uppercase ml-4 px-4">
|
||||
Informations pour pour votre page
|
||||
</div>
|
||||
<div class="flex flex-col w-full ">
|
||||
<button
|
||||
@click="openDialog('CreateCreator')"
|
||||
class="HoverBtn active:bg-gray-300 py-2 px-4 border-gray-400 shadow flex items-center transition duration-200 ease-in-out"
|
||||
>
|
||||
<span class="flex-none pa-2 min-w-32 text-left">Nom</span>
|
||||
<span class="flex-auto text-left pr-6"
|
||||
>Choisissez le nom de votre page. Cela peut être un nom de personne, d'organisation ou de projet.</span
|
||||
>
|
||||
<span class="flex-none">
|
||||
<v-icon>mdi-chevron-right</v-icon>
|
||||
</span>
|
||||
</button>
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -347,7 +303,7 @@ const closeDialog = () => {
|
||||
@apply bg-[#A6147D] text-white;
|
||||
@apply hover:opacity-90;
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
.custom-border {
|
||||
|
||||
Reference in New Issue
Block a user