updates
This commit is contained in:
parent
e5b8affa84
commit
cf4af2cbff
|
|
@ -94,12 +94,17 @@
|
||||||
<v-list-item-title :class="mobile ? 'text-body-2' : ''">Client Signature Link</v-list-item-title>
|
<v-list-item-title :class="mobile ? 'text-body-2' : ''">Client Signature Link</v-list-item-title>
|
||||||
<v-list-item-subtitle :class="mobile ? 'text-caption' : ''">{{ interest['Full Name'] }}</v-list-item-subtitle>
|
<v-list-item-subtitle :class="mobile ? 'text-caption' : ''">{{ interest['Full Name'] }}</v-list-item-subtitle>
|
||||||
<template v-slot:append>
|
<template v-slot:append>
|
||||||
<v-btn
|
<v-btn-group variant="text" :size="mobile ? 'small' : 'default'">
|
||||||
icon="mdi-content-copy"
|
<v-btn
|
||||||
variant="text"
|
icon="mdi-content-copy"
|
||||||
:size="mobile ? 'small' : 'default'"
|
@click="copyLink(interest['Signature Link Client'])"
|
||||||
@click="copyLink(interest['Signature Link Client'])"
|
></v-btn>
|
||||||
></v-btn>
|
<v-btn
|
||||||
|
icon="mdi-open-in-new"
|
||||||
|
:href="interest['Signature Link Client']"
|
||||||
|
target="_blank"
|
||||||
|
></v-btn>
|
||||||
|
</v-btn-group>
|
||||||
</template>
|
</template>
|
||||||
</v-list-item>
|
</v-list-item>
|
||||||
|
|
||||||
|
|
@ -112,12 +117,17 @@
|
||||||
<v-list-item-title :class="mobile ? 'text-body-2' : ''">CC Signature Link</v-list-item-title>
|
<v-list-item-title :class="mobile ? 'text-body-2' : ''">CC Signature Link</v-list-item-title>
|
||||||
<v-list-item-subtitle :class="mobile ? 'text-caption' : ''">Oscar Faragher</v-list-item-subtitle>
|
<v-list-item-subtitle :class="mobile ? 'text-caption' : ''">Oscar Faragher</v-list-item-subtitle>
|
||||||
<template v-slot:append>
|
<template v-slot:append>
|
||||||
<v-btn
|
<v-btn-group variant="text" :size="mobile ? 'small' : 'default'">
|
||||||
icon="mdi-content-copy"
|
<v-btn
|
||||||
variant="text"
|
icon="mdi-content-copy"
|
||||||
:size="mobile ? 'small' : 'default'"
|
@click="copyLink(interest['Signature Link CC'])"
|
||||||
@click="copyLink(interest['Signature Link CC'])"
|
></v-btn>
|
||||||
></v-btn>
|
<v-btn
|
||||||
|
icon="mdi-open-in-new"
|
||||||
|
:href="interest['Signature Link CC']"
|
||||||
|
target="_blank"
|
||||||
|
></v-btn>
|
||||||
|
</v-btn-group>
|
||||||
</template>
|
</template>
|
||||||
</v-list-item>
|
</v-list-item>
|
||||||
|
|
||||||
|
|
@ -130,12 +140,17 @@
|
||||||
<v-list-item-title :class="mobile ? 'text-body-2' : ''">Developer Signature Link</v-list-item-title>
|
<v-list-item-title :class="mobile ? 'text-body-2' : ''">Developer Signature Link</v-list-item-title>
|
||||||
<v-list-item-subtitle :class="mobile ? 'text-caption' : ''">David Mizrahi</v-list-item-subtitle>
|
<v-list-item-subtitle :class="mobile ? 'text-caption' : ''">David Mizrahi</v-list-item-subtitle>
|
||||||
<template v-slot:append>
|
<template v-slot:append>
|
||||||
<v-btn
|
<v-btn-group variant="text" :size="mobile ? 'small' : 'default'">
|
||||||
icon="mdi-content-copy"
|
<v-btn
|
||||||
variant="text"
|
icon="mdi-content-copy"
|
||||||
:size="mobile ? 'small' : 'default'"
|
@click="copyLink(interest['Signature Link Developer'])"
|
||||||
@click="copyLink(interest['Signature Link Developer'])"
|
></v-btn>
|
||||||
></v-btn>
|
<v-btn
|
||||||
|
icon="mdi-open-in-new"
|
||||||
|
:href="interest['Signature Link Developer']"
|
||||||
|
target="_blank"
|
||||||
|
></v-btn>
|
||||||
|
</v-btn-group>
|
||||||
</template>
|
</template>
|
||||||
</v-list-item>
|
</v-list-item>
|
||||||
</v-list>
|
</v-list>
|
||||||
|
|
|
||||||
|
|
@ -139,14 +139,25 @@ const getAttachmentName = (attachment: any) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
const getAttachmentUrl = (attachment: any) => {
|
const getAttachmentUrl = (attachment: any) => {
|
||||||
// If attachment has a path and bucket, construct the download URL
|
// If attachment is just a string (filename), assume it's in the client-emails bucket
|
||||||
if (attachment.path && attachment.bucket) {
|
if (typeof attachment === 'string') {
|
||||||
return `/api/files/proxy-download?path=${encodeURIComponent(attachment.path)}&bucket=${attachment.bucket}`;
|
return `/api/files/proxy-download?fileName=${encodeURIComponent(attachment)}&bucket=client-emails`;
|
||||||
}
|
}
|
||||||
// If it's just a URL, return it
|
|
||||||
if (attachment.url) return attachment.url;
|
// If it has a path property, use that
|
||||||
// Otherwise return a placeholder
|
if (attachment?.path) {
|
||||||
return '#';
|
const bucket = attachment.bucket || 'client-emails';
|
||||||
|
return `/api/files/proxy-download?fileName=${encodeURIComponent(attachment.path)}&bucket=${bucket}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If it has a url property, use that directly
|
||||||
|
if (attachment?.url) {
|
||||||
|
return attachment.url;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Default fallback
|
||||||
|
const name = attachment?.name || attachment?.filename || 'attachment';
|
||||||
|
return `/api/files/proxy-download?fileName=${encodeURIComponent(name)}&bucket=client-emails`;
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -196,7 +196,7 @@
|
||||||
</v-col>
|
</v-col>
|
||||||
<v-col cols="12">
|
<v-col cols="12">
|
||||||
<v-btn
|
<v-btn
|
||||||
@click="() => debouncedSaveInterest ? debouncedSaveInterest() : saveInterest()"
|
@click="handleMobileSave"
|
||||||
variant="flat"
|
variant="flat"
|
||||||
color="success"
|
color="success"
|
||||||
block
|
block
|
||||||
|
|
@ -407,46 +407,8 @@
|
||||||
prepend-inner-icon="mdi-tag"
|
prepend-inner-icon="mdi-tag"
|
||||||
></v-select>
|
></v-select>
|
||||||
</v-col>
|
</v-col>
|
||||||
<v-col cols="12" md="6">
|
<!-- Berth Recommendations field hidden per user request -->
|
||||||
<v-autocomplete
|
<v-col cols="12" md="12">
|
||||||
v-model="selectedBerthRecommendations"
|
|
||||||
:items="groupedBerths"
|
|
||||||
:item-title="(item) => item.isDivider ? '' : item['Mooring Number']"
|
|
||||||
:item-value="(item) => item.isDivider ? null : item.Id"
|
|
||||||
label="Berth Recommendations"
|
|
||||||
variant="outlined"
|
|
||||||
density="comfortable"
|
|
||||||
multiple
|
|
||||||
chips
|
|
||||||
closable-chips
|
|
||||||
:loading="loadingBerths"
|
|
||||||
prepend-inner-icon="mdi-star"
|
|
||||||
@update:model-value="updateBerthRecommendations"
|
|
||||||
>
|
|
||||||
<template v-slot:item="{ props, item }">
|
|
||||||
<v-divider v-if="item.raw.isDivider" class="mt-2 mb-2">
|
|
||||||
<template v-slot:default>
|
|
||||||
<div class="text-caption text-medium-emphasis px-2">
|
|
||||||
{{ item.raw.letter }}
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
</v-divider>
|
|
||||||
<v-list-item
|
|
||||||
v-else
|
|
||||||
v-bind="props"
|
|
||||||
:title="item.raw['Mooring Number']"
|
|
||||||
/>
|
|
||||||
</template>
|
|
||||||
<template v-slot:chip="{ props, item }">
|
|
||||||
<v-chip
|
|
||||||
v-bind="props"
|
|
||||||
:text="item.raw['Mooring Number']"
|
|
||||||
size="small"
|
|
||||||
></v-chip>
|
|
||||||
</template>
|
|
||||||
</v-autocomplete>
|
|
||||||
</v-col>
|
|
||||||
<v-col cols="12" md="6">
|
|
||||||
<v-autocomplete
|
<v-autocomplete
|
||||||
v-model="selectedBerths"
|
v-model="selectedBerths"
|
||||||
:items="groupedBerths"
|
:items="groupedBerths"
|
||||||
|
|
@ -1094,9 +1056,18 @@ const updateBerths = async (newBerths: number[]) => {
|
||||||
|
|
||||||
// Update original values
|
// Update original values
|
||||||
originalBerths.value = [...newBerths];
|
originalBerths.value = [...newBerths];
|
||||||
|
|
||||||
|
// Show success message
|
||||||
|
if (toAdd.length > 0 || toRemove.length > 0) {
|
||||||
|
toast.success("Berths updated successfully");
|
||||||
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Failed to update berths:", error);
|
console.error("Failed to update berths:", error);
|
||||||
toast.error("Failed to update berths. Please try again.");
|
// Show more specific error message on mobile
|
||||||
|
const errorMessage = mobile.value
|
||||||
|
? "Could not update berths. Please check your connection and try again."
|
||||||
|
: "Failed to update berths. Please try again.";
|
||||||
|
toast.error(errorMessage);
|
||||||
// Revert to original values on error
|
// Revert to original values on error
|
||||||
selectedBerths.value = [...originalBerths.value];
|
selectedBerths.value = [...originalBerths.value];
|
||||||
}
|
}
|
||||||
|
|
@ -1302,6 +1273,20 @@ const onInterestUpdated = async () => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Handle mobile save - call the save function directly without debounce
|
||||||
|
const handleMobileSave = () => {
|
||||||
|
console.log('Mobile save button clicked');
|
||||||
|
// Cancel any pending debounced saves
|
||||||
|
if (debouncedSaveInterest) {
|
||||||
|
debouncedSaveInterest.cancel();
|
||||||
|
}
|
||||||
|
if (autoSave) {
|
||||||
|
autoSave.cancel();
|
||||||
|
}
|
||||||
|
// Call save directly
|
||||||
|
saveInterest();
|
||||||
|
};
|
||||||
|
|
||||||
// Load berths when component mounts
|
// Load berths when component mounts
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
loadAvailableBerths();
|
loadAvailableBerths();
|
||||||
|
|
|
||||||
|
|
@ -125,7 +125,7 @@
|
||||||
:headers="headers"
|
:headers="headers"
|
||||||
:items="filteredInterests"
|
:items="filteredInterests"
|
||||||
:search="search"
|
:search="search"
|
||||||
:sort-by="[{ key: 'Created At', order: 'desc' }, { key: 'Full Name', order: 'asc' }]"
|
:sort-by="[{ key: 'Id', order: 'desc' }]"
|
||||||
must-sort
|
must-sort
|
||||||
hover
|
hover
|
||||||
:loading="loading"
|
:loading="loading"
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,9 @@ export default defineEventHandler(async (event) => {
|
||||||
throw createError({ statusCode: 401, statusMessage: "unauthenticated" });
|
throw createError({ statusCode: 401, statusMessage: "unauthenticated" });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set longer timeout for this endpoint to prevent 502 errors
|
||||||
|
event.node.res.setTimeout(60000); // 60 seconds
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const body = await readBody(event);
|
const body = await readBody(event);
|
||||||
const { interestId } = body;
|
const { interestId } = body;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue