chore(photos): simplify photo components
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
<template>
|
||||
<template>
|
||||
<div class="p-4 relative"
|
||||
@mouseenter="showEditButtons = isLoggedIn && creatorProfileStore.creator?.id === brandingStore.value.id"
|
||||
@mouseleave="showEditButtons = false">
|
||||
@@ -46,7 +46,7 @@
|
||||
{{ t('creator.sections.about.title') }}
|
||||
</h1>
|
||||
|
||||
<div>
|
||||
<div>
|
||||
<!-- Description Section -->
|
||||
<div>
|
||||
<div v-if="!isEditMode">
|
||||
@@ -68,9 +68,9 @@
|
||||
rows="5"
|
||||
variant="outlined"></v-textarea>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- Video Section -->
|
||||
<div v-if="videoUrl || isEditMode"
|
||||
<div v-if="videoUrl || isEditMode"
|
||||
:class="['content-section', {
|
||||
'rounded-t-xl': hasImages && !isEditMode,
|
||||
'rounded-xl': !hasImages && !isEditMode
|
||||
@@ -98,18 +98,21 @@
|
||||
</div>
|
||||
|
||||
<!-- Photos Section using Album component -->
|
||||
<Album
|
||||
v-if="hasImages || isEditMode"
|
||||
:is-edit-mode="isEditMode"
|
||||
:images="imageUrls"
|
||||
@update:images="updateImages"
|
||||
@update:isEditMode="isEditMode = $event"
|
||||
:class="['content-section', {
|
||||
'rounded-b-xl': videoUrl && !isEditMode,
|
||||
'rounded-xl': !videoUrl && !isEditMode
|
||||
}]"
|
||||
/>
|
||||
<div>
|
||||
<!-- Use AlbumView for display mode -->
|
||||
<AlbumView v-if="!isEditMode && hasImages"
|
||||
:images="imageUrls"
|
||||
:class="['content-section', {
|
||||
'rounded-b-xl': videoUrl && !isEditMode,
|
||||
'rounded-xl': !videoUrl && !isEditMode
|
||||
}]"/>
|
||||
|
||||
<!-- Use AlbumEditor for edit mode -->
|
||||
<AlbumEditor v-if="isEditMode"
|
||||
:images="imageUrls"
|
||||
@update:images="updateImages"/>
|
||||
</div>
|
||||
|
||||
<!-- Contact Information Section -->
|
||||
<div v-if="phoneNumber || email" class="contact-info mt-6">
|
||||
<!-- Phone Number -->
|
||||
@@ -135,6 +138,8 @@ import {useCreatorProfileStore} from "@/stores/creatorProfileStore.js";
|
||||
import {useI18n} from 'vue-i18n';
|
||||
import Album from './Album.vue';
|
||||
import {buildEmbedUrl, isValidYouTubeUrlOrId, extractVideoId} from '@/utils/youtube';
|
||||
import AlbumEditor from "@/views/creators/AlbumEditor.vue";
|
||||
import AlbumView from "@/views/creators/AlbumView.vue";
|
||||
|
||||
const {t} = useI18n();
|
||||
const creatorProfileStore = useCreatorProfileStore();
|
||||
@@ -167,17 +172,17 @@ const canSave = computed(() => {
|
||||
if (!editableDescription.value || editableDescription.value.trim() === '') {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// Check if description is too long
|
||||
if (editableDescription.value.length > 2000) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// Check if video URL is invalid (if one is provided)
|
||||
if (editableVideoUrl.value && !validateVideoUrl(editableVideoUrl.value)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
});
|
||||
|
||||
@@ -199,12 +204,12 @@ function validateVideoUrl(url) {
|
||||
videoUrlError.value = "";
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
if (!isValidYouTubeUrlOrId(url)) {
|
||||
videoUrlError.value = t('creator.validation.invalidYoutubeUrl');
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
videoUrlError.value = "";
|
||||
return true;
|
||||
}
|
||||
@@ -228,13 +233,13 @@ function toggleEditMode() {
|
||||
// Fetch album data
|
||||
async function fetchAlbumData() {
|
||||
if (!brandingStore.value?.id) return;
|
||||
|
||||
|
||||
albumId.value = brandingStore.value.id;
|
||||
|
||||
|
||||
try {
|
||||
// Try to get the album
|
||||
const response = await client.get(`/api/albums/${albumId.value}`);
|
||||
|
||||
|
||||
if (response.data && response.data.photos) {
|
||||
// Store original photos for comparison
|
||||
originalPhotos.value = response.data.photos;
|
||||
@@ -315,7 +320,7 @@ async function saveChanges() {
|
||||
if (imageUrls.value.length > 0) {
|
||||
// Create or update the album
|
||||
const albumId = brandingStore.value.id;
|
||||
|
||||
|
||||
try {
|
||||
// Try to create the album first (it will fail if it already exists)
|
||||
await client.post('/api/albums', {
|
||||
@@ -327,13 +332,13 @@ async function saveChanges() {
|
||||
// Album might already exist, which is fine
|
||||
console.log("Album might already exist:", error);
|
||||
}
|
||||
|
||||
|
||||
// Check for deleted photos
|
||||
const deletedPhotos = originalPhotos.value.filter(originalPhoto => {
|
||||
// If the photo URL is not in the current images array, it was deleted
|
||||
return !imageUrls.value.includes(originalPhoto.photoUrl);
|
||||
});
|
||||
|
||||
|
||||
// Delete removed photos
|
||||
for (const photo of deletedPhotos) {
|
||||
try {
|
||||
@@ -342,7 +347,7 @@ async function saveChanges() {
|
||||
console.error("Error deleting photo:", error);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Now add or update photos
|
||||
for (let i = 0; i < imageUrls.value.length; i++) {
|
||||
const imageUrl = imageUrls.value[i];
|
||||
@@ -350,14 +355,14 @@ async function saveChanges() {
|
||||
// This is a new image that needs to be uploaded
|
||||
const photoId = crypto.randomUUID();
|
||||
const formData = new FormData();
|
||||
|
||||
|
||||
// Convert data URL to file
|
||||
const response = await fetch(imageUrl);
|
||||
const blob = await response.blob();
|
||||
const file = new File([blob], `photo-${i}.jpg`, { type: 'image/jpeg' });
|
||||
|
||||
const file = new File([blob], `photo-${i}.jpg`, {type: 'image/jpeg'});
|
||||
|
||||
formData.append('file', file);
|
||||
|
||||
|
||||
await client.post(`/api/albums/${albumId}/photos`, formData, {
|
||||
headers: {
|
||||
'Content-Type': 'multipart/form-data'
|
||||
@@ -368,7 +373,7 @@ async function saveChanges() {
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Refresh album data after changes
|
||||
await fetchAlbumData();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user