feat(events): accept 'TBD' as a valid location
Events are often scheduled before the platform (Zoom link, Slack channel) is chosen. The current workaround is a placeholder URL like "https://us02web.zoom.us/j/TBD", which leaks to the public page as a broken link. Accept the literal "TBD" (case-insensitive) in both the Mongoose validator and the form-side validator. The public detail page renders "Platform TBD" instead of a link when the location matches.
This commit is contained in:
parent
e1d224e260
commit
6fa3e08fe0
3 changed files with 16 additions and 12 deletions
|
|
@ -114,7 +114,7 @@
|
||||||
<label> Location <span class="required">*</span> </label>
|
<label> Location <span class="required">*</span> </label>
|
||||||
<UInput
|
<UInput
|
||||||
v-model="eventForm.location"
|
v-model="eventForm.location"
|
||||||
placeholder="e.g., https://zoom.us/j/123... or #channel-name"
|
placeholder="e.g., https://zoom.us/j/123..., #channel-name, or TBD"
|
||||||
required
|
required
|
||||||
:color="fieldErrors.location ? 'error' : undefined"
|
:color="fieldErrors.location ? 'error' : undefined"
|
||||||
class="w-full"
|
class="w-full"
|
||||||
|
|
@ -123,7 +123,8 @@
|
||||||
{{ fieldErrors.location }}
|
{{ fieldErrors.location }}
|
||||||
</p>
|
</p>
|
||||||
<p v-if="!fieldErrors.location" class="help-text">
|
<p v-if="!fieldErrors.location" class="help-text">
|
||||||
Enter a video conference link or Slack channel (starting with #)
|
Video conference link, Slack channel (#channel-name), or 'TBD' if
|
||||||
|
the platform is undecided
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
@ -840,7 +841,7 @@ const validateForm = () => {
|
||||||
if (!eventForm.location.trim()) {
|
if (!eventForm.location.trim()) {
|
||||||
formErrors.value.push("Location is required");
|
formErrors.value.push("Location is required");
|
||||||
fieldErrors.value.location =
|
fieldErrors.value.location =
|
||||||
"Please enter a location (URL or Slack channel)";
|
"Please enter a URL, Slack channel, or 'TBD'";
|
||||||
}
|
}
|
||||||
|
|
||||||
// Date validation
|
// Date validation
|
||||||
|
|
@ -861,18 +862,17 @@ const validateForm = () => {
|
||||||
|
|
||||||
// Location format validation
|
// Location format validation
|
||||||
if (eventForm.location.trim()) {
|
if (eventForm.location.trim()) {
|
||||||
|
const value = eventForm.location.trim();
|
||||||
const urlPattern = /^https?:\/\/.+/;
|
const urlPattern = /^https?:\/\/.+/;
|
||||||
const slackPattern = /^#[a-zA-Z0-9-_]+$/;
|
const slackPattern = /^#[a-zA-Z0-9-_]+$/;
|
||||||
|
const isTbd = value.toUpperCase() === "TBD";
|
||||||
|
|
||||||
if (
|
if (!isTbd && !urlPattern.test(value) && !slackPattern.test(value)) {
|
||||||
!urlPattern.test(eventForm.location) &&
|
|
||||||
!slackPattern.test(eventForm.location)
|
|
||||||
) {
|
|
||||||
formErrors.value.push(
|
formErrors.value.push(
|
||||||
"Location must be a valid URL or Slack channel (starting with #)",
|
"Location must be a valid URL, Slack channel (starting with #), or 'TBD'",
|
||||||
);
|
);
|
||||||
fieldErrors.value.location =
|
fieldErrors.value.location =
|
||||||
"Enter a video conference link (https://...) or Slack channel (#channel-name)";
|
"Enter a URL (https://...), Slack channel (#channel-name), or 'TBD' if undecided";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,10 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="event-meta-item">
|
<div class="event-meta-item">
|
||||||
<span class="meta-label">Location</span>
|
<span class="meta-label">Location</span>
|
||||||
{{ event.location }}
|
<span v-if="event.location?.trim().toUpperCase() === 'TBD'">
|
||||||
|
Platform TBD
|
||||||
|
</span>
|
||||||
|
<template v-else>{{ event.location }}</template>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="event.circle" class="event-meta-item">
|
<div v-if="event.circle" class="event-meta-item">
|
||||||
<CircleBadge :circle="event.circle" />
|
<CircleBadge :circle="event.circle" />
|
||||||
|
|
|
||||||
|
|
@ -25,13 +25,14 @@ const eventSchema = new mongoose.Schema({
|
||||||
// This will typically be a Slack channel or video conference link
|
// This will typically be a Slack channel or video conference link
|
||||||
validate: {
|
validate: {
|
||||||
validator: function (v) {
|
validator: function (v) {
|
||||||
// Must be either a valid URL or a Slack channel reference
|
// Accept a URL, a Slack channel, or the literal "TBD" (platform undecided).
|
||||||
|
if (typeof v === "string" && v.trim().toUpperCase() === "TBD") return true;
|
||||||
const urlPattern = /^https?:\/\/.+/;
|
const urlPattern = /^https?:\/\/.+/;
|
||||||
const slackPattern = /^#[a-zA-Z0-9-_]+$/;
|
const slackPattern = /^#[a-zA-Z0-9-_]+$/;
|
||||||
return urlPattern.test(v) || slackPattern.test(v);
|
return urlPattern.test(v) || slackPattern.test(v);
|
||||||
},
|
},
|
||||||
message:
|
message:
|
||||||
"Location must be a valid URL (video conference link) or Slack channel (starting with #)",
|
"Location must be a valid URL, Slack channel (starting with #), or 'TBD'",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
isOnline: { type: Boolean, default: true }, // Default to online-first
|
isOnline: { type: Boolean, default: true }, // Default to online-first
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue