This commit is contained in:
2025-02-07 15:44:59 -05:00
parent 2b30479263
commit 009368ca8f
38 changed files with 1815 additions and 945 deletions

View File

@@ -1,95 +1,89 @@
<template>
<div class="flex flex-col items-center w-[800px] gap-4">
<h1 class="uppercase pb-5 text-2xl">
<v-icon class="mr-2">mdi-information</v-icon>
{{ $t('personnalinformation.title') }}
</h1>
<v-card rounded="xl" class="w-full">
<v-card class="w-full">
<v-card-title>
{{ $t('personnalinformation.informations') }}
</v-card-title>
<v-card-title>
{{ $t('personnalinformation.informations') }}
</v-card-title>
<!-- <button-->
<!-- class="editableValue"-->
<!-- @click="openEditPortrait">-->
<!-- <span class="label">{{ $t('personnalinformation.profilepicture') }}</span>-->
<!-- <span class="value">Un portrait vous permet de personnaliser votre profil</span>-->
<!-- <span>-->
<!-- <img-->
<!-- :src="userProfileStore.user.portraitUrl"-->
<!-- alt="Profile Image"-->
<!-- class="rounded-full"-->
<!-- width="48px"-->
<!-- height="48px"/>-->
<!-- </span>-->
<!-- </button>-->
<!-- <button-->
<!-- class="editableValue"-->
<!-- @click="openEditPortrait">-->
<!-- <span class="label">{{ $t('personnalinformation.profilepicture') }}</span>-->
<!-- <span class="value">Un portrait vous permet de personnaliser votre profil</span>-->
<!-- <span>-->
<!-- <img-->
<!-- :src="userProfileStore.user.portraitUrl"-->
<!-- alt="Profile Image"-->
<!-- class="rounded-full"-->
<!-- width="48px"-->
<!-- height="48px"/>-->
<!-- </span>-->
<!-- </button>-->
<button
class="editableValue"
@click="openEditFullname">
<span class="label">{{ $t('personnalinformation.fullname') }}</span>
<span class="value">{{ userProfileStore.fullname }}</span>
<span><v-icon>mdi-chevron-right</v-icon></span>
</button>
<button
class="editableValue"
@click="openEditFullname">
<span class="label">{{ $t('personnalinformation.fullname') }}</span>
<span class="value">{{ userProfileStore.fullname }}</span>
<span><v-icon>mdi-chevron-right</v-icon></span>
</button>
<button
class="editableValue"
@click="openEditAlias">
<span class="label">{{ $t('personnalinformation.alias') }}</span>
<span class="value">{{ userProfileStore.user.alias }}</span>
<span><v-icon>mdi-chevron-right</v-icon></span>
</button>
<button
class="editableValue"
@click="openEditAlias">
<span class="label">{{ $t('personnalinformation.alias') }}</span>
<span class="value">{{ userProfileStore.user.alias }}</span>
<span><v-icon>mdi-chevron-right</v-icon></span>
</button>
<!-- <button-->
<!-- class="editableValue"-->
<!-- @click="openEditBirthday">-->
<!-- <span class="label">{{ $t('personnalinformation.dob') }}</span>-->
<!-- <span class="value">{{ userProfileStore.user.birthDate }}</span>-->
<!-- <span><v-icon>mdi-chevron-right</v-icon></span>-->
<!-- </button>-->
<!-- <button-->
<!-- class="editableValue"-->
<!-- @click="openEditBirthday">-->
<!-- <span class="label">{{ $t('personnalinformation.dob') }}</span>-->
<!-- <span class="value">{{ userProfileStore.user.birthDate }}</span>-->
<!-- <span><v-icon>mdi-chevron-right</v-icon></span>-->
<!-- </button>-->
</v-card>
</v-card>
<!-- Phone & email -->
<v-card class="w-full">
<v-card-title>
{{ $t('personnalinformation.contactdetails') }}
</v-card-title>
<!-- Phone & email -->
<v-card rounded="xl" class="w-full">
<v-card-title>
{{ $t('personnalinformation.contactdetails') }}
</v-card-title>
<button
class="editableValue"
@click="openEditEmail">
<span class="label">{{ $t('personnalinformation.email') }}</span>
<span class="value">{{ userProfileStore.user.email }}</span>
<span><v-icon>mdi-chevron-right</v-icon></span>
</button>
<button
class="editableValue"
@click="openEditEmail">
<span class="label">{{ $t('personnalinformation.email') }}</span>
<span class="value">{{ userProfileStore.user.email }}</span>
<span><v-icon>mdi-chevron-right</v-icon></span>
</button>
<!-- <button-->
<!-- class="editableValue"-->
<!-- @click="openEditPhone">-->
<!-- <span class="label">{{ $t('personnalinformation.phone') }}</span>-->
<!-- <span class="value">{{ userProfileStore.user.phoneNumber }}</span>-->
<!-- <span><v-icon>mdi-chevron-right</v-icon></span>-->
<!-- </button>-->
</v-card>
<!-- <button-->
<!-- class="editableValue"-->
<!-- @click="openEditPhone">-->
<!-- <span class="label">{{ $t('personnalinformation.phone') }}</span>-->
<!-- <span class="value">{{ userProfileStore.user.phoneNumber }}</span>-->
<!-- <span><v-icon>mdi-chevron-right</v-icon></span>-->
<!-- </button>-->
</v-card>
<!-- Address -->
<!-- <v-card class="w-full">-->
<!-- <v-card-title>-->
<!-- {{ $t('personnalinformation.addresses') }}-->
<!-- </v-card-title>-->
<!-- Address -->
<!-- <v-card class="w-full">-->
<!-- <v-card-title>-->
<!-- {{ $t('personnalinformation.addresses') }}-->
<!-- </v-card-title>-->
<!-- <button-->
<!-- class="editableValue"-->
<!-- @click="openEditAddress">-->
<!-- <span class="label">{{ $t('personnalinformation.home') }}</span>-->
<!-- <span class="value">{{ userProfileStore.user.address }}</span>-->
<!-- <span><v-icon>mdi-chevron-right</v-icon></span>-->
<!-- </button>-->
<!-- </v-card>-->
</div>
<!-- <button-->
<!-- class="editableValue"-->
<!-- @click="openEditAddress">-->
<!-- <span class="label">{{ $t('personnalinformation.home') }}</span>-->
<!-- <span class="value">{{ userProfileStore.user.address }}</span>-->
<!-- <span><v-icon>mdi-chevron-right</v-icon></span>-->
<!-- </button>-->
<!-- </v-card>-->
<!-- Modal -->
<v-dialog v-model="dialogEditPortraitShown" max-width="600px">
@@ -152,8 +146,8 @@
<script setup>
import {ref} from 'vue';
import AddressDialog from './AddressDialog.vue';
import EmailDialog from "./EmailDialog.vue";
import AddressDialog from './account/AddressDialog.vue';
import EmailDialog from "./account/EmailDialog.vue";
import PhoneDialog from "@/views/profile/account/PhoneDialog.vue";
import BirthdayDialog from "@/views/profile/account/BirthdayDialog.vue";
import AliasDialog from "@/views/profile/account/AliasDialog.vue";

View File

@@ -0,0 +1,283 @@
<script setup>
import XIcon from '@/assets/icons/x.svg';
import {useCreatorProfileStore} from '@/stores/creatorProfileStore.js';
import ChangeStripeID from '@/views/profile/creators/ChangeStripeID.vue';
import ChangeTitle from '@/views/profile/creators/ChangeTitle.vue';
import {computed, ref} from 'vue';
import ColorsPicker from './creators/ColorsPicker.vue';
import LogoPicker from '../creators/CreatorLogoEditor.vue';
import Socials from './creators/Socials.vue';
const creatorProfileStore = useCreatorProfileStore();
const dialog = ref(false);
const currentComponent = ref('');
const componentsMap = {
LogoPicker,
Socials,
ColorsPicker,
ChangeTitle,
ChangeStripeID,
};
function requestCancel() {
currentComponent.value = null;
dialog.value = false;
}
const openDialog = (component) => {
currentComponent.value = componentsMap[component];
dialog.value = true;
};
const closeDialog = () => {
currentComponent.value = null;
dialog.value = false;
};
</script>
<template>
<v-dialog v-model="dialog" max-width="800px">
<v-card
:style="{ borderRadius: '25px', border: '3px solid rgb(159, 76, 173)' }"
>
<v-card-text>
<component
:is="currentComponent"
:creator="creatorProfileStore.creator"
@closeRequested="closeDialog"
@requestAccept="requestAccept"
@requestCancel="requestCancel"
></component>
</v-card-text>
</v-card>
</v-dialog>
<!-- Lorsque l'utilisateur n'a pas de creator name-->
<v-card rounded="xl" class="w-full">>
<h1 class="uppercase">
{{ $t('creatorinfopage.informations') }}
</h1>
<!-- INFOS -->
<div class="flex flex-col w-full">
<button
class="HoverBtn active:bg-gray-300 py-2 px-4 border-gray-400 shadow flex items-center transition duration-200 ease-in-out w-full"
>
<span class="flex-none pa-2 min-w-32 text-left">
{{ $t('creatorinfopage.name') }}
</span>
<span class="flex-auto text-left pr-6 capitalize">
{{ creatorProfileStore.creator.name }}
</span>
<span class="flex-none">
<v-icon>mdi-chevron-right</v-icon>
</span>
</button>
</div>
<!-- TITLE -->
<div class="flex flex-col w-full">
<button
@click="openDialog('ChangeTitle')"
class="HoverBtn active:bg-gray-300 py-2 px-4 border-gray-400 shadow flex items-center transition duration-200 ease-in-out w-full"
>
<span class="flex-none pa-2 min-w-32 text-left">{{
$t('creatorinfopage.title')
}}</span>
<span class="flex-auto text-left pr-6 capitalize">{{
creatorProfileStore.creator.title
}}</span>
<span class="flex-none">
<v-icon>mdi-chevron-right</v-icon>
</span>
</button>
</div>
<!-- STRIPE -->
<div class="flex flex-col w-full">
<button
@click="openDialog('ChangeStripeID')"
class="HoverBtn active:bg-gray-300 py-2 px-4 border-gray-400 shadow flex items-center transition duration-200 ease-in-out w-full rounded-b"
>
<span class="flex-none pa-2 min-w-32 text-left"
>Stripe Account ID</span
>
<span class="flex-auto text-left pr-6">{{
creatorProfileStore.creator.stripeId
}}</span>
<span class="flex-none">
<v-icon>mdi-chevron-right</v-icon>
</span>
</button>
</div>
</v-card>
<v-card rounded="xl" class="w-full">
<div class="py-5 uppercase ml-4">
{{ $t('creatorinfopage.banner&profile') }}
</div>
<div class="flex flex-col w-full">
<button
@click="openDialog('ColorsPicker')"
class="HoverBtn active:bg-gray-300 py-2 px-4 border-gray-400 shadow flex items-center transition duration-200 ease-in-out w-full"
>
<span class="flex-auto text-left pr-6 capitalize">
Choisissez votre palette de couleurs.
</span>
<span class="flex-none">
<v-icon>mdi-chevron-right</v-icon>
</span>
</button>
</div>
</v-card>
<v-card rounded="xl" class="w-full">
<div class="uppercase">
{{ $t('creatorinfopage.socialnetwork') }}
</div>
<div class="flex flex-col w-full">
<button
@click="openDialog('Socials')"
class="HoverBtn active:bg-gray-300 py-2 px-4 border-gray-400 shadow flex items-center transition duration-200 ease-in-out w-full"
>
<span class="pa-2 min-w-32 text-left">
<v-icon>mdi-facebook</v-icon>
</span>
<span class="flex-auto text-left pr-6">
{{ creatorProfileStore.creator.socials?.facebookUrl }}
</span>
<span class="flex-none">
<v-icon>mdi-chevron-right</v-icon>
</span>
</button>
<button
@click="openDialog('Socials')"
class="HoverBtn active:bg-gray-300 py-2 px-4 border-gray-400 shadow flex items-center transition duration-200 ease-in-out w-full"
>
<span class="flex-none pa-2 min-w-32 text-left">
<v-icon>mdi-instagram</v-icon></span
>
<span class="flex-auto text-left pr-6">{{
creatorProfileStore.creator.socials?.instagramUrl
}}</span>
<span class="flex-none">
<v-icon>mdi-chevron-right</v-icon>
</span>
</button>
<button
@click="openDialog('Socials')"
class="HoverBtn active:bg-gray-300 py-2 px-4 border-gray-400 shadow flex items-center transition duration-200 ease-in-out w-full"
>
<span class="flex-none pa-2 w-9 h-9 text-left ml-0.5">
<XIcon></XIcon>
</span>
<span class="flex-auto text-left pr-6">{{
creatorProfileStore.creator.socials?.xUrl
}}</span>
<span class="flex-none">
<v-icon>mdi-chevron-right</v-icon>
</span>
</button>
<button
@click="openDialog('Socials')"
class="HoverBtn active:bg-gray-300 py-2 px-4 border-gray-400 shadow flex items-center transition duration-200 ease-in-out w-full"
>
<span class="pa-2 min-w-32 text-left"
><v-icon>mdi-linkedin</v-icon></span
>
<span class="flex-auto text-left pr-6">{{
creatorProfileStore.creator.socials?.linkedInUrl
}}</span>
<span class="flex-none">
<v-icon>mdi-chevron-right</v-icon>
</span>
</button>
<button
@click="openDialog('Socials')"
class="HoverBtn active:bg-gray-300 py-2 px-4 border-gray-400 shadow flex items-center transition duration-200 ease-in-out w-full"
>
<span class="flex-none pa-2 min-w-32 text-left">
<XIcon class="w-5 h-5"></XIcon>
</span>
<span class="flex-auto text-left pr-6">{{
creatorProfileStore.creator.socials?.tikTokUrl
}}</span>
<span class="flex-none">
<v-icon>mdi-chevron-right</v-icon>
</span>
</button>
<button
@click="openDialog('Socials')"
class="HoverBtn active:bg-gray-300 py-2 px-4 border-gray-400 shadow flex items-center transition duration-200 ease-in-out w-full"
>
<span class="pa-2 min-w-32 text-left"
><v-icon>mdi-youtube</v-icon></span
>
<span class="flex-auto text-left pr-6">{{
creatorProfileStore.creator.socials?.youtubeUrl
}}</span>
<span class="flex-none">
<v-icon>mdi-chevron-right</v-icon>
</span>
</button>
<button
@click="openDialog('Socials')"
class="HoverBtn active:bg-gray-300 py-2 px-4 border-gray-400 shadow flex items-center transition duration-200 ease-in-out w-full"
>
<span class="pa-2 min-w-32 text-left"
><v-icon>mdi-reddit</v-icon></span
>
<span class="flex-auto text-left pr-6">{{
creatorProfileStore.creator.socials?.redditUrl
}}</span>
<span class="flex-none">
<v-icon>mdi-chevron-right</v-icon>
</span>
</button>
<button
@click="openDialog('Socials')"
class="HoverBtn active:bg-gray-300 py-2 px-4 border-gray-400 shadow flex items-center transition duration-200 ease-in-out w-full rounded-b"
>
<span class="pa-2 min-w-32 text-left"
><v-icon>mdi-web</v-icon></span
>
<span class="flex-auto text-left pr-6">{{
creatorProfileStore.creator.socials?.websiteUrl
}}</span>
<span class="flex-none">
<v-icon>mdi-chevron-right</v-icon>
</span>
</button>
</div>
</v-card>
</template>
<style>
.HoverBtn:hover {
@apply bg-[#A6147D] text-white;
@apply hover:opacity-90;
}
.custom-border {
border: 3px solid;
}
</style>

View File

@@ -1,147 +1,16 @@
<template>
<!-- Mobile -->
<div v-if="isMobileView" class="flex flex-col items-center justify-center min-h-screen bg-gray-100 p-6 text-center">
<!-- Image -->
<img src="/images/usersmedia/HutopyProfile/profilepictures/profileHutopyProfile01.png" alt="Image" class="w-64 h-64 rounded-full mb-4 border" />
<!-- Message -->
<div class="text-lg text-gray-700 mt-8">
<p class="font-semibold mb-2">Pour vous connecter et modifier votre page, veuillez utiliser un appareil avec un écran plus large, comme un ordinateur.</p>
<p>Pour le moment, l'expérience sur téléphone n'est pas encore complétée.</p>
<p class="mt-4 font-bold">Désolé de l'inconvénient.</p>
</div>
<div class="bg-red flex flex-col gap-8 p-8">
<account-page></account-page>
<creator-page></creator-page>
</div>
<!-- PC -->
<div v-else>
<div class="flex flex-col md:flex-row bg-[#f4f4f4] h-full">
<!-- Left Menu -->
<div class=" z-20 w-full md:max-w-xs fixed md:sticky md:top-0 md:flex md:flex-col top-0">
<div class="sticky top-20 z-30">
<div class="flex flex-col items-center md:items-start md:pl-4 mt-16">
<h1 class="text-2xl py-4 font-bold text-center md:text-left">{{$t('profilemenu.manageyouraccount')}}</h1>
<div class="relative flex items-center md:mt-0 w-full">
<!-- Navigation buttons for small screens -->
<button @click="scrollLeftFunc"
class="rounded p-1 absolute left-2 z-10 md:hidden text-fuchsia-800 text-2xl ">
<v-icon>mdi-chevron-left</v-icon>
</button>
<div
ref="scrollContainer"
class="flex md:flex-col space-x-2 space-y-0 md:space-x-0 md:space-y-2 p-4 items-center md:items-start overflow-x-scroll md:overflow-x-visible mx-2 md:mx-0 custom-scroll min-w-[400px] px-1"
@mousedown="mouseDown"
@mouseleave="mouseLeave"
@mouseup="mouseUp"
@mousemove="mouseMove">
<v-btn variant="text" @click="currentComponent = 'CreatorPage'">
<v-icon class="mr-2">mdi-file-edit-outline</v-icon>
{{ $t('profilemenu.creator') }}
</v-btn>
<v-btn variant="text" @click="currentComponent = 'AccountPage'">
<v-icon class="mr-2">mdi-information</v-icon>
{{ $t('profilemenu.user') }}
</v-btn>
</div>
<button @click="scrollRightFunc"
class="rounded p-1 absolute right-2 z-10 md:hidden text-fuchsia-800 bg-[#f4f4f4] text-2xl">
<v-icon>mdi-chevron-right</v-icon>
</button>
</div>
</div>
</div>
</div>
<!-- Mid Content -->
<div class="flex flex-col flex-1 align-center py-12 p-3 mt-28 md:mt-0">
<template v-if="currentComponent === 'CreatorPage'">
<creator-page></creator-page>
</template>
<template v-else-if="currentComponent === 'AccountPage'">
<account-page></account-page>
</template>
</div>
</div>
</div>
</template>
<script setup>
import { ref, watch } from "vue";
import CreatorPage from "@/views/profile/creators/CreatorPage.vue";
import AccountPage from "@/views/profile/account/AccountPage.vue";
import { useRoute } from "vue-router";
import { useDisplay } from "vuetify";
const { smAndDown } = useDisplay();
const route = useRoute();
const startingComponent = route.query.target || 'CreatorPage';
const currentComponent = ref(startingComponent);
const isMobileView = ref(smAndDown.value);
watch(smAndDown, (newVal) => {
isMobileView.value = newVal;
});
// Gestion du slider (scroll sur petit écran)
const isDown = ref(false);
const startX = ref(0);
const scrollLeft = ref(0);
const mouseDown = (e) => {
const slider = document.querySelector('.custom-scroll');
isDown.value = true;
slider.classList.add('active');
startX.value = e.pageX - slider.offsetLeft;
scrollLeft.value = slider.scrollLeft;
};
const mouseLeave = () => {
isDown.value = false;
const slider = document.querySelector('.custom-scroll');
slider.classList.remove('active');
};
const mouseUp = () => {
isDown.value = false;
const slider = document.querySelector('.custom-scroll');
slider.classList.remove('active');
};
const mouseMove = (e) => {
if (!isDown.value) return;
e.preventDefault();
const slider = document.querySelector('.custom-scroll');
const x = e.pageX - slider.offsetLeft;
const walk = (x - startX.value) * 3; // scroll-fast
slider.scrollLeft = scrollLeft.value - walk;
};
const scrollLeftFunc = () => {
const container = document.querySelector('.custom-scroll');
container.scrollBy({ left: -100, behavior: 'smooth' });
};
const scrollRightFunc = () => {
const container = document.querySelector('.custom-scroll');
container.scrollBy({ left: 100, behavior: 'smooth' });
};
import CreatorPage from "@/views/profile/CreatorPage.vue";
import AccountPage from "@/views/profile/AccountPage.vue";
</script>
<style scoped>
.custom-scroll {
-ms-overflow-style: none; /* Internet Explorer 10+ */
scrollbar-width: none; /* Firefox */
}
.custom-scroll::-webkit-scrollbar {
display: none; /* Safari and Chrome */
}
</style>

View File

@@ -1,75 +0,0 @@
<template>
<h2 class="text-2xl font-semibold mb-4 flex justify-center">
Bannière
</h2>
<img
:src="fileUrl || fallbackUrl"
class="mb-5 w-full transition duration-200 ease-in-out transform"
alt="Aperçu de la bannière"
>
<v-file-input
v-model="selectedFile"
variant="outlined"
accept="image/*"
label="Votre bannière"
@change="onFileSelected"
></v-file-input>
<div class="flex justify-end space-x-4">
<v-btn color="black" variant="text" @click="cancel">Annuler</v-btn>
<v-btn color="#A6147D" @click="publish">Enregistrer</v-btn>
</div>
</template>
<script setup>
import { ref } from 'vue'
import { useClient } from '@/plugins/api.js'
const props = defineProps({
creator: {
required: true
}
})
const emits = defineEmits(['closeRequested'])
const selectedFile = ref({})
const fileUrl = ref(props.creator.images.banner)
const fallbackUrl = '/images/hutopymedia/banners/hutopyul.png'
const onFileSelected = () => {
if (selectedFile.value) {
const reader = new FileReader()
reader.onload = (event) => {
fileUrl.value = event.target.result
}
reader.readAsDataURL(selectedFile.value)
} else {
fileUrl.value = null
}
}
const client = useClient()
const publish = async () => {
try {
const formData = new FormData()
formData.append('file', selectedFile.value)
await client.post(
`/api/creators/${props.creator.id}/banner`,
formData
)
props.creator.images.banner = fileUrl
emits('closeRequested')
} catch (error) {
console.error(error)
}
}
const cancel = () => {
emits('closeRequested')
}
</script>

View File

@@ -1,6 +1,6 @@
<script setup>
import { ref } from 'vue';
import { useClient } from '@/plugins/api.js';
import {ref} from 'vue';
import {useClient} from '@/plugins/api.js';
const props = defineProps({
creator: {
@@ -14,7 +14,7 @@ const title = ref(props.creator.title);
const client = useClient();
const save = async () => {
async function save() {
try {
await client.post(
`/api/creators/${props.creator.id}/title`,
@@ -28,7 +28,7 @@ const save = async () => {
} catch (error) {
console.error('Error saving title:', error);
}
};
}
const cancel = () => {
emits('closeRequested');
@@ -56,6 +56,7 @@ const cancel = () => {
.flex {
display: flex;
}
.space-y-4 > * + * {
margin-top: 1rem;
}

View File

@@ -1,84 +0,0 @@
<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 creatorName = ref('');
const errorMessage = ref('');
const isLoading = ref(false);
const router = useRouter();
const creatorProfileStore = useCreatorProfileStore();
const userProfileStore = useUserProfileStore();
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;
}
}
</script>
<template>
<div>
<div class="create-creator-card">
<div class="py-2 text-3xl font-bold">
<div class="text-center mb-10">Créez votre Hutopy.</div>
</div>
<div class="flex flex-column justify-end gap-2">
<v-alert
v-if="!!errorMessage"
dense
outlined
text
type="error"
>
{{ errorMessage }}
</v-alert>
<v-text-field
variant="outlined"
v-model="creatorName"
label="Nom de la page"
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>
</div>
</template>
<style scoped>
.create-creator-card {
@apply text-center max-w-[1000px] mx-auto p-10 bg-white shadow-2xl rounded mt-16 ;
}
</style>

View File

@@ -1,312 +0,0 @@
<script setup>
import XIcon from '@/assets/icons/x.svg';
import { useCreatorProfileStore } from '@/stores/creatorProfileStore.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 LogoPicker from './LogoPicker.vue';
import Socials from './Socials.vue';
const creatorProfileStore = useCreatorProfileStore();
console.log(creatorProfileStore.creator);
const imageBanner = computed(
() =>
creatorProfileStore.creator.images.banner ||
'/images/placeholders/banner.png'
);
const imageLogo = computed(
() =>
creatorProfileStore.creator.images.logo || '/images/placeholders/logo.png'
);
const dialog = ref(false);
const currentComponent = ref('');
const componentsMap = {
BannerPicker,
LogoPicker,
Socials,
ColorsPicker,
ChangeTitle,
ChangeStripeID,
};
function requestCancel() {
currentComponent.value = null;
dialog.value = false;
}
const openDialog = (component) => {
currentComponent.value = componentsMap[component];
dialog.value = true;
};
const closeDialog = () => {
currentComponent.value = null;
dialog.value = false;
};
</script>
<template>
<v-dialog v-model="dialog" max-width="800px">
<v-card
:style="{ borderRadius: '25px', border: '3px solid rgb(159, 76, 173)' }"
>
<v-card-text>
<component
:is="currentComponent"
:creator="creatorProfileStore.creator"
@closeRequested="closeDialog"
@requestAccept="requestAccept"
@requestCancel="requestCancel"
></component>
</v-card-text>
</v-card>
</v-dialog>
<!-- Lorsque l'utilisateur n'a pas de creator name-->
<div class="flex flex-col items-center w-full">
<h1 class="uppercase pb-5 text-2xl">
<v-icon class="mr-2">mdi-file-edit-outline</v-icon>
{{ $t('creatorinfopage.pageinformation') }}
</h1>
<div v-if="creatorProfileStore.hasCreator" class="w-full max-w-[800px]">
<div class="my-10 border rounded bg-white">
<div class="py-5 uppercase ml-4">
{{ $t('creatorinfopage.informations') }}
</div>
<div class="flex flex-col w-full">
<button
class="HoverBtn active:bg-gray-300 py-2 px-4 border-gray-400 shadow flex items-center transition duration-200 ease-in-out w-full"
>
<span class="flex-none pa-2 min-w-32 text-left">{{
$t('creatorinfopage.name')
}}</span>
<span class="flex-auto text-left pr-6 capitalize">{{
creatorProfileStore.creator.name
}}</span>
<span class="flex-none">
<v-icon>mdi-chevron-right</v-icon>
</span>
</button>
</div>
<div class="flex flex-col w-full">
<button
@click="openDialog('ChangeTitle')"
class="HoverBtn active:bg-gray-300 py-2 px-4 border-gray-400 shadow flex items-center transition duration-200 ease-in-out w-full"
>
<span class="flex-none pa-2 min-w-32 text-left">{{
$t('creatorinfopage.title')
}}</span>
<span class="flex-auto text-left pr-6 capitalize">{{
creatorProfileStore.creator.title
}}</span>
<span class="flex-none">
<v-icon>mdi-chevron-right</v-icon>
</span>
</button>
</div>
<div class="flex flex-col w-full">
<button
@click="openDialog('ChangeStripeID')"
class="HoverBtn active:bg-gray-300 py-2 px-4 border-gray-400 shadow flex items-center transition duration-200 ease-in-out w-full rounded-b"
>
<span class="flex-none pa-2 min-w-32 text-left"
>Stripe Account ID</span
>
<span class="flex-auto text-left pr-6">{{
creatorProfileStore.creator.stripeId
}}</span>
<span class="flex-none">
<v-icon>mdi-chevron-right</v-icon>
</span>
</button>
</div>
</div>
<div class="border rounded bg-white">
<div class="py-5 uppercase ml-4">
{{ $t('creatorinfopage.banner&profile') }}
</div>
<div class="flex flex-col w-full gap-4">
<button
@click="openDialog('ColorsPicker')"
class="HoverBtn active:bg-gray-300 py-2 px-4 border-gray-400 shadow flex items-center transition duration-200 ease-in-out w-full"
>
<span class="flex-auto text-left pr-6 capitalize">
Choisissez votre palette de couleurs.
</span>
<span class="flex-none">
<v-icon>mdi-chevron-right</v-icon>
</span>
</button>
<button>
<img
@click="openDialog('BannerPicker')"
:src="imageBanner"
class="w-full transition duration-200 ease-in-out transform hover:brightness-125"
alt="Tutorial Banner"
/>
</button>
<button class="flex justify-center my-5">
<img
@click="openDialog('LogoPicker')"
class="custom-border hover:brightness-125 active:bg-gray-600 shadow flex items-center transition duration-200 ease-in-out w-48 h-48 rounded-full"
:src="imageLogo"
alt="Profile Image"
/>
</button>
</div>
</div>
<div class="mt-10 border rounded bg-white">
<div class="py-5 uppercase ml-4">
{{ $t('creatorinfopage.socialnetwork') }}
</div>
<div class="flex flex-col w-full ">
<button
@click="openDialog('Socials')"
class="HoverBtn active:bg-gray-300 py-2 px-4 border-gray-400 shadow flex items-center transition duration-200 ease-in-out w-full"
>
<span class="pa-2 min-w-32 text-left"
><v-icon>mdi-facebook</v-icon></span
>
<span class="flex-auto text-left pr-6">{{
creatorProfileStore.creator.socials.facebookUrl
}}</span>
<span class="flex-none">
<v-icon>mdi-chevron-right</v-icon>
</span>
</button>
<button
@click="openDialog('Socials')"
class="HoverBtn active:bg-gray-300 py-2 px-4 border-gray-400 shadow flex items-center transition duration-200 ease-in-out w-full"
>
<span class="flex-none pa-2 min-w-32 text-left">
<v-icon>mdi-instagram</v-icon></span
>
<span class="flex-auto text-left pr-6">{{
creatorProfileStore.creator.socials.instagramUrl
}}</span>
<span class="flex-none">
<v-icon>mdi-chevron-right</v-icon>
</span>
</button>
<button
@click="openDialog('Socials')"
class="HoverBtn active:bg-gray-300 py-2 px-4 border-gray-400 shadow flex items-center transition duration-200 ease-in-out w-full"
>
<span class="flex-none pa-2 w-9 h-9 text-left ml-0.5">
<XIcon></XIcon>
</span>
<span class="flex-auto text-left pr-6">{{
creatorProfileStore.creator.socials.xUrl
}}</span>
<span class="flex-none">
<v-icon>mdi-chevron-right</v-icon>
</span>
</button>
<button
@click="openDialog('Socials')"
class="HoverBtn active:bg-gray-300 py-2 px-4 border-gray-400 shadow flex items-center transition duration-200 ease-in-out w-full"
>
<span class="pa-2 min-w-32 text-left"
><v-icon>mdi-linkedin</v-icon></span
>
<span class="flex-auto text-left pr-6">{{
creatorProfileStore.creator.socials.linkedInUrl
}}</span>
<span class="flex-none">
<v-icon>mdi-chevron-right</v-icon>
</span>
</button>
<button
@click="openDialog('Socials')"
class="HoverBtn active:bg-gray-300 py-2 px-4 border-gray-400 shadow flex items-center transition duration-200 ease-in-out w-full"
>
<span class="flex-none pa-2 min-w-32 text-left">
<XIcon class="w-5 h-5"></XIcon>
</span>
<span class="flex-auto text-left pr-6">{{
creatorProfileStore.creator.socials.tikTokUrl
}}</span>
<span class="flex-none">
<v-icon>mdi-chevron-right</v-icon>
</span>
</button>
<button
@click="openDialog('Socials')"
class="HoverBtn active:bg-gray-300 py-2 px-4 border-gray-400 shadow flex items-center transition duration-200 ease-in-out w-full"
>
<span class="pa-2 min-w-32 text-left"
><v-icon>mdi-youtube</v-icon></span
>
<span class="flex-auto text-left pr-6">{{
creatorProfileStore.creator.socials.youtubeUrl
}}</span>
<span class="flex-none">
<v-icon>mdi-chevron-right</v-icon>
</span>
</button>
<button
@click="openDialog('Socials')"
class="HoverBtn active:bg-gray-300 py-2 px-4 border-gray-400 shadow flex items-center transition duration-200 ease-in-out w-full"
>
<span class="pa-2 min-w-32 text-left"
><v-icon>mdi-reddit</v-icon></span
>
<span class="flex-auto text-left pr-6">{{
creatorProfileStore.creator.socials.redditUrl
}}</span>
<span class="flex-none">
<v-icon>mdi-chevron-right</v-icon>
</span>
</button>
<button
@click="openDialog('Socials')"
class="HoverBtn active:bg-gray-300 py-2 px-4 border-gray-400 shadow flex items-center transition duration-200 ease-in-out w-full rounded-b"
>
<span class="pa-2 min-w-32 text-left"
><v-icon>mdi-web</v-icon></span
>
<span class="flex-auto text-left pr-6">{{
creatorProfileStore.creator.socials.websiteUrl
}}</span>
<span class="flex-none">
<v-icon>mdi-chevron-right</v-icon>
</span>
</button>
</div>
</div>
</div>
</div>
</template>
<style>
.HoverBtn:hover {
@apply bg-[#A6147D] text-white;
@apply hover:opacity-90;
}
.custom-border {
border: 3px solid;
}
</style>

View File

@@ -1,78 +0,0 @@
<template>
<h2 class="text-2xl font-semibold mb-4 flex justify-center">
Logo
</h2>
<div class="flex justify-center mb-5">
<img
:src="fileUrl || fallbackUrl"
class="w-full transition duration-200 ease-in-out transform max-w-[400px]"
alt="Aperçu du logo"
/>
</div>
<v-file-input
v-model="selectedFile"
variant="outlined"
accept="image/*"
label="Votre logo"
@change="onFileSelected"
></v-file-input>
<div class="flex justify-end space-x-4">
<v-btn color="black" variant="text" @click="cancel">Annuler</v-btn>
<v-btn color="#A6147D" @click="publish">Enregistrer</v-btn>
</div>
</template>
<script setup>
import { ref } from 'vue'
import { useClient } from '@/plugins/api.js'
const props = defineProps({
creator: {
required: true
}
})
const emits = defineEmits(['closeRequested'])
const selectedFile = ref("")
const fileUrl = ref(props.creator.images.logo)
const fallbackUrl = '/images/usersmedia/HutopyProfile/profilepictures/profileHutopyProfile01.png' // Chemin de votre image de secours
const onFileSelected = () => {
if (selectedFile.value) {
const reader = new FileReader()
reader.onload = (event) => {
fileUrl.value = event.target.result
}
reader.readAsDataURL(selectedFile.value)
} else {
fileUrl.value = null
}
}
const client = useClient()
const publish = async () => {
try {
const formData = new FormData();
formData.append('file', selectedFile.value)
await client.post(
`/api/creators/${props.creator.id}/logo`,
formData)
props.creator.images.logo = fileUrl.value;
emits('closeRequested');
} catch (error) {
console.error(error)
}
}
const cancel = () => {
emits('closeRequested')
}
</script>