fix(album): improving the creation/update workflow
This commit is contained in:
@@ -17,16 +17,12 @@ export function useClient() {
|
||||
|
||||
// Request interceptor
|
||||
client.interceptors.request.use(async (config) => {
|
||||
console.log(`Request interceptor triggered for: ${config.method?.toUpperCase()} ${config.url}`);
|
||||
|
||||
// Check if this is the refresh token endpoint
|
||||
const isRefreshEndpoint = config.url?.includes('api/users/refresh');
|
||||
|
||||
// Check if we need to refresh the token
|
||||
if (authStore.isAuthenticated && !isRefreshEndpoint) {
|
||||
try {
|
||||
console.log(`User is authenticated, checking token for: ${config.method?.toUpperCase()} ${config.url}`);
|
||||
|
||||
// If token is expiring soon, start a refresh and WAIT for it to complete
|
||||
if (authStore.isTokenExpiringSoon(authStore.accessToken)) {
|
||||
console.log(`Token is expiring soon, waiting for refresh to complete before continuing request: ${config.method?.toUpperCase()} ${config.url}`);
|
||||
@@ -40,10 +36,7 @@ export function useClient() {
|
||||
}
|
||||
|
||||
if (authStore.isAuthenticated && !isRefreshEndpoint) {
|
||||
console.log(`Setting Authorization header for: ${config.method?.toUpperCase()} ${config.url}`);
|
||||
config.headers.Authorization = `Bearer ${authStore.accessToken}`;
|
||||
} else if (isRefreshEndpoint) {
|
||||
console.log(`Skipping Authorization header for refresh endpoint: ${config.method?.toUpperCase()} ${config.url}`);
|
||||
}
|
||||
|
||||
if (config.data instanceof FormData) {
|
||||
@@ -58,7 +51,6 @@ export function useClient() {
|
||||
// Response interceptor
|
||||
client.interceptors.response.use(
|
||||
(response) => {
|
||||
console.log(`Response received successfully for: ${response.config.method?.toUpperCase()} ${response.config.url}`);
|
||||
return response;
|
||||
},
|
||||
async (error) => {
|
||||
@@ -91,7 +83,6 @@ export function useClient() {
|
||||
// If it's a refresh request that failed, or a retry that still failed, give up
|
||||
if (originalRequest.url.includes('api/users/refresh') || originalRequest._retry) {
|
||||
console.log(`Request permanently failed: ${originalRequest.method?.toUpperCase()} ${originalRequest.url}`);
|
||||
// Don't do anything here, let the refresh error handling work
|
||||
}
|
||||
|
||||
return Promise.reject(error);
|
||||
|
||||
@@ -26,7 +26,6 @@ export const useAuthStore = defineStore('auth', () => {
|
||||
const userId = computed(() => tokenClaims.value?.sub);
|
||||
|
||||
function updateTokens(data) {
|
||||
console.log('updateTokens called with response data:', data);
|
||||
if (!data?.accessToken || !data?.refreshToken) {
|
||||
throw new Error('Invalid token data');
|
||||
}
|
||||
@@ -207,8 +206,6 @@ export const useAuthStore = defineStore('auth', () => {
|
||||
}
|
||||
|
||||
function isTokenExpiringSoon(token) {
|
||||
console.log('isTokenExpiringSoon called');
|
||||
|
||||
if (!token) {
|
||||
console.log('No token provided, considered expiring soon');
|
||||
return true;
|
||||
@@ -235,11 +232,13 @@ export const useAuthStore = defineStore('auth', () => {
|
||||
? `-${formatDuration(Math.abs(timeRemainingMs))}`
|
||||
: formatDuration(timeRemainingMs);
|
||||
|
||||
if (isExpiring) {
|
||||
console.log(`Token expiration check; is token expired: ${isExpiring}`, {
|
||||
expirationTime: new Date(expirationTime).toLocaleString(),
|
||||
currentTime: new Date(currentTime).toLocaleString(),
|
||||
timeRemaining: formattedTimeRemaining
|
||||
});
|
||||
}
|
||||
|
||||
return isExpiring;
|
||||
}
|
||||
|
||||
@@ -214,11 +214,11 @@ async function fetchAlbumData() {
|
||||
console.log('in fetchAlbumData()');
|
||||
if (!brandingStore.value?.id) return;
|
||||
|
||||
albumId.value = brandingStore.value.id;
|
||||
const creatorId = brandingStore.value.id;
|
||||
|
||||
try {
|
||||
// Try to get the album
|
||||
const response = await client.get(`/api/albums/${albumId.value}`);
|
||||
const response = await client.get(`/api/albums/${creatorId}`);
|
||||
|
||||
if (response.data && response.data.photos) {
|
||||
// Store original photos for comparison
|
||||
@@ -230,15 +230,15 @@ async function fetchAlbumData() {
|
||||
isProcessing: false,
|
||||
isUploading: false,
|
||||
}));
|
||||
albumId.value = creatorId;
|
||||
} else {
|
||||
// Initialize with empty array instead of empty slots
|
||||
console.log('WOW! You found how to get here! Take a look at the stack!');
|
||||
photos.value = [];
|
||||
originalPhotos.value = [];
|
||||
}
|
||||
} catch (error) {
|
||||
// Album might not exist yet, which is fine
|
||||
console.log("Album might not exist yet:", error);
|
||||
// Initialize with empty array instead of empty slots
|
||||
}
|
||||
catch (error) {
|
||||
photos.value = [];
|
||||
originalPhotos.value = [];
|
||||
}
|
||||
@@ -302,46 +302,48 @@ async function saveChanges() {
|
||||
videoUrl.value = extractVideoId(editableVideoUrl.value) || "";
|
||||
|
||||
// Check for deleted photos
|
||||
console.log('originalPhotos', originalPhotos.value);
|
||||
console.log('photos', photos.value);
|
||||
const photosOriginalUrls = photos.value.map(photo => photo.image.originalUrl);
|
||||
console.log('photosThumbnailUrls', photosOriginalUrls);
|
||||
const deletedPhotos = originalPhotos.value.filter(originalPhoto => {
|
||||
// If the photo URL is not in the current images array, it was deleted
|
||||
return !photosOriginalUrls.includes(originalPhoto.originalUrl);
|
||||
});
|
||||
const newImages = photos.value.filter(photo => photo && photo.image && photo.image.originalUrl.startsWith('data:'));
|
||||
|
||||
console.log('originalPhotos', originalPhotos.value);
|
||||
console.log('photos', photos.value);
|
||||
console.log('deletedPhotos', deletedPhotos);
|
||||
console.log('newImages', newImages);
|
||||
|
||||
// Save album photos if they've changed
|
||||
if (photos.value.length > 0 || deletedPhotos.length > 0) {
|
||||
// Create or update the album
|
||||
const albumId = brandingStore.value.id;
|
||||
console.log('We got pending changes');
|
||||
|
||||
// Create the Album if we do not have one yet
|
||||
if (albumId.value == null) {
|
||||
console.log('We do not have an album yet')
|
||||
try {
|
||||
// Try to create the album first (it will fail if it already exists)
|
||||
await client.post('/api/albums', {
|
||||
albumId: albumId,
|
||||
albumId: brandingStore.value.id,
|
||||
title: `${brandingStore.value.name}'s Album`,
|
||||
description: "Photo album for the creator"
|
||||
});
|
||||
albumId.value = brandingStore.value.id;
|
||||
} catch (error) {
|
||||
// Album might already exist, which is fine
|
||||
console.log("Album might already exist:", error);
|
||||
console.log("Couldn't create an Album", error);
|
||||
}
|
||||
}
|
||||
|
||||
// Delete removed photos
|
||||
for (const photo of deletedPhotos) {
|
||||
try {
|
||||
await client.delete(`/api/albums/${albumId}/photos/${photo.id}`);
|
||||
await client.delete(`/api/albums/${albumId.value}/photos/${photo.id}`);
|
||||
} catch (error) {
|
||||
console.error("Error deleting photo:", error);
|
||||
}
|
||||
}
|
||||
|
||||
// Now add or update photos
|
||||
const newImages = photos.value.filter(photo => photo && photo.image && photo.image.originalUrl.startsWith('data:'));
|
||||
console.log('newImages', newImages);
|
||||
for (let i = 0; i < newImages.length; i++) {
|
||||
const imageData = newImages[i];
|
||||
console.log('Image Data to be uploaded:', imageData);
|
||||
@@ -356,7 +358,7 @@ async function saveChanges() {
|
||||
|
||||
formData.append('file', file);
|
||||
|
||||
await client.post(`/api/albums/${albumId}/photos`, formData, {
|
||||
await client.post(`/api/albums/${albumId.value}/photos`, formData, {
|
||||
headers: {
|
||||
'Content-Type': 'multipart/form-data'
|
||||
},
|
||||
|
||||
@@ -1,95 +0,0 @@
|
||||
<template>
|
||||
<div v-if="hasImages || isEditMode"
|
||||
class="creator-album"
|
||||
@click="handleAlbumClick">
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { computed } from "vue";
|
||||
import AlbumView from './AlbumView.vue';
|
||||
import AlbumEditor from './AlbumEditor.vue';
|
||||
|
||||
const props = defineProps({
|
||||
isEditMode: {
|
||||
type: Boolean,
|
||||
required: true
|
||||
},
|
||||
images: {
|
||||
type: Array,
|
||||
required: true,
|
||||
default: () => []
|
||||
}
|
||||
});
|
||||
|
||||
const emit = defineEmits(['update:images']);
|
||||
|
||||
// Computed property to check if there are images
|
||||
const hasImages = computed(() => {
|
||||
return props.images.some(url => url);
|
||||
});
|
||||
|
||||
// Handle album click to enter edit mode
|
||||
function handleAlbumClick() {
|
||||
if (!props.isEditMode) {
|
||||
emit('update:isEditMode', true);
|
||||
}
|
||||
}
|
||||
|
||||
// Update images from AlbumEditor component
|
||||
function updateImages(newImages) {
|
||||
emit('update:images', newImages);
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.creator-album {
|
||||
@apply w-full;
|
||||
cursor: pointer;
|
||||
}
|
||||
</style>
|
||||
|
||||
<i18n>
|
||||
{
|
||||
"en": {
|
||||
"common": {
|
||||
"delete": "Delete"
|
||||
},
|
||||
"creator": {
|
||||
"sections": {
|
||||
"album": {
|
||||
"title": "Photo Album",
|
||||
"image": "Album image"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"fr": {
|
||||
"common": {
|
||||
"delete": "Supprimer"
|
||||
},
|
||||
"creator": {
|
||||
"sections": {
|
||||
"album": {
|
||||
"title": "Album photo",
|
||||
"image": "Image de l'album"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"es": {
|
||||
"common": {
|
||||
"delete": "Eliminar"
|
||||
},
|
||||
"creator": {
|
||||
"sections": {
|
||||
"album": {
|
||||
"title": "Álbum de fotos",
|
||||
"image": "Imagen del álbum"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</i18n>
|
||||
@@ -58,7 +58,7 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, onMounted, watch } from "vue";
|
||||
import { ref, onMounted } from "vue";
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { v7 } from 'uuid';
|
||||
import draggable from 'vuedraggable';
|
||||
@@ -81,10 +81,6 @@ onMounted(() => {
|
||||
localImages.value = props.images;
|
||||
});
|
||||
|
||||
watch(localImages, (newVal) => {
|
||||
console.log('localImages changed:', newVal);
|
||||
}, { deep: true });
|
||||
|
||||
function handleFiles(files) {
|
||||
console.log('handleFiles:', files)
|
||||
for (const file of files) {
|
||||
|
||||
Reference in New Issue
Block a user